From 743edc0cad80722bdaaf025cbd98bd869d11dd6e Mon Sep 17 00:00:00 2001 From: kram Date: Thu, 2 Nov 2017 17:11:14 -0700 Subject: [PATCH 01/58] initial barefoot checkin october 2017 --- .gitmodules | 6 +- .../installer.conf | 1 + .../minigraph.xml | 1079 ++++++++ .../montara/port_config.ini | 33 + .../installer.conf | 1 + .../mavericks/port_config.ini | 66 + .../minigraph.xml | 1079 ++++++++ dockers/docker-bfn-sswsyncd-rpc/Dockerfile | 38 + dockers/docker-bfn-sswsyncd/Dockerfile | 17 + dockers/docker-orchagent-bfn | 1 + dockers/docker-orchagent/orchagent.sh | 2 + dockers/docker-saiserver-bfn/Dockerfile | 38 + dockers/docker-saiserver-bfn/portmap.ini | 33 + dockers/docker-saiserver-bfn/profile.ini | 1 + dockers/docker-saiserver-bfn/sai_tofino.xml | 2 + dockers/docker-saiserver-bfn/start.sh | 16 + dockers/docker-saiserver-bfn/supervisord.conf | 29 + files/image_config/interfaces/interfaces.j2 | 5 + platform/barefoot/bfn-sai.mk | 6 + platform/barefoot/docker-orchagent-bfn.mk | 18 + platform/barefoot/docker-ptf-bfn.mk | 5 + platform/barefoot/docker-syncd-bfn-rpc.mk | 15 + .../docker-syncd-bfn-rpc/Dockerfile.j2 | 52 + .../docker-syncd-bfn-rpc/ptf_nn_agent.conf | 10 + platform/barefoot/docker-syncd-bfn.mk | 15 + .../barefoot/docker-syncd-bfn/Dockerfile.j2 | 29 + platform/barefoot/docker-syncd-bfn/start.sh | 9 + .../docker-syncd-bfn/supervisord.conf | 29 + platform/barefoot/libsaithrift-dev.mk | 7 + platform/barefoot/one-image.mk | 11 + .../barefoot/platform-modules-bfn-montara.mk | 11 + platform/barefoot/platform-modules-bfn.mk | 11 + platform/barefoot/platform.conf | 0 platform/barefoot/python-saithrift.mk | 6 + platform/barefoot/rules.mk | 19 + .../LICENSE | 15 + .../MAINTAINERS | 7 + .../README.md | 2 + .../debian/changelog | 5 + .../debian/compat | 1 + .../debian/control | 12 + .../debian/copyright | 15 + .../debian/files | 1 + .../debian/rules | 32 + .../modules/Makefile | 1 + .../modules/bf_kdrv.c | 1 + .../modules/bf_tun.c | 1 + .../scripts/test | 1 + .../sonic-platform-modules-bfn/LICENSE | 15 + .../sonic-platform-modules-bfn/MAINTAINERS | 7 + .../sonic-platform-modules-bfn/README.md | 2 + .../debian/changelog | 5 + .../sonic-platform-modules-bfn/debian/compat | 1 + .../sonic-platform-modules-bfn/debian/control | 12 + .../debian/copyright | 15 + .../sonic-platform-modules-bfn/debian/files | 1 + .../sonic-platform-modules-bfn/debian/rules | 32 + .../modules/Makefile | 2 + .../modules/bf_kdrv.c | 1152 ++++++++ .../modules/bf_tun.c | 2396 +++++++++++++++++ .../sonic-platform-modules-bfn/scripts/test | 1 + sonic-slave/Dockerfile | 3 + .../tests/sample_output/interfaces | 5 + src/sonic-sairedis | 2 +- src/sonic-swss | 2 +- 65 files changed, 6442 insertions(+), 5 deletions(-) create mode 100644 device/barefoot/x86_64-accton_wedge100bf_32x-r0/installer.conf create mode 100644 device/barefoot/x86_64-accton_wedge100bf_32x-r0/minigraph.xml create mode 100644 device/barefoot/x86_64-accton_wedge100bf_32x-r0/montara/port_config.ini create mode 100644 device/barefoot/x86_64-accton_wedge100bf_65x-r0/installer.conf create mode 100644 device/barefoot/x86_64-accton_wedge100bf_65x-r0/mavericks/port_config.ini create mode 100644 device/barefoot/x86_64-accton_wedge100bf_65x-r0/minigraph.xml create mode 100644 dockers/docker-bfn-sswsyncd-rpc/Dockerfile create mode 100755 dockers/docker-bfn-sswsyncd/Dockerfile create mode 120000 dockers/docker-orchagent-bfn create mode 100755 dockers/docker-saiserver-bfn/Dockerfile create mode 100644 dockers/docker-saiserver-bfn/portmap.ini create mode 100644 dockers/docker-saiserver-bfn/profile.ini create mode 100644 dockers/docker-saiserver-bfn/sai_tofino.xml create mode 100755 dockers/docker-saiserver-bfn/start.sh create mode 100644 dockers/docker-saiserver-bfn/supervisord.conf create mode 100644 platform/barefoot/bfn-sai.mk create mode 100644 platform/barefoot/docker-orchagent-bfn.mk create mode 100644 platform/barefoot/docker-ptf-bfn.mk create mode 100644 platform/barefoot/docker-syncd-bfn-rpc.mk create mode 100644 platform/barefoot/docker-syncd-bfn-rpc/Dockerfile.j2 create mode 100644 platform/barefoot/docker-syncd-bfn-rpc/ptf_nn_agent.conf create mode 100644 platform/barefoot/docker-syncd-bfn.mk create mode 100755 platform/barefoot/docker-syncd-bfn/Dockerfile.j2 create mode 100755 platform/barefoot/docker-syncd-bfn/start.sh create mode 100644 platform/barefoot/docker-syncd-bfn/supervisord.conf create mode 100644 platform/barefoot/libsaithrift-dev.mk create mode 100644 platform/barefoot/one-image.mk create mode 100644 platform/barefoot/platform-modules-bfn-montara.mk create mode 100644 platform/barefoot/platform-modules-bfn.mk create mode 100644 platform/barefoot/platform.conf create mode 100644 platform/barefoot/python-saithrift.mk create mode 100644 platform/barefoot/rules.mk create mode 100644 platform/barefoot/sonic-platform-modules-bfn-montara/LICENSE create mode 100644 platform/barefoot/sonic-platform-modules-bfn-montara/MAINTAINERS create mode 100644 platform/barefoot/sonic-platform-modules-bfn-montara/README.md create mode 100644 platform/barefoot/sonic-platform-modules-bfn-montara/debian/changelog create mode 100644 platform/barefoot/sonic-platform-modules-bfn-montara/debian/compat create mode 100644 platform/barefoot/sonic-platform-modules-bfn-montara/debian/control create mode 100644 platform/barefoot/sonic-platform-modules-bfn-montara/debian/copyright create mode 100644 platform/barefoot/sonic-platform-modules-bfn-montara/debian/files create mode 100755 platform/barefoot/sonic-platform-modules-bfn-montara/debian/rules create mode 120000 platform/barefoot/sonic-platform-modules-bfn-montara/modules/Makefile create mode 120000 platform/barefoot/sonic-platform-modules-bfn-montara/modules/bf_kdrv.c create mode 120000 platform/barefoot/sonic-platform-modules-bfn-montara/modules/bf_tun.c create mode 100755 platform/barefoot/sonic-platform-modules-bfn-montara/scripts/test create mode 100644 platform/barefoot/sonic-platform-modules-bfn/LICENSE create mode 100644 platform/barefoot/sonic-platform-modules-bfn/MAINTAINERS create mode 100644 platform/barefoot/sonic-platform-modules-bfn/README.md create mode 100644 platform/barefoot/sonic-platform-modules-bfn/debian/changelog create mode 100644 platform/barefoot/sonic-platform-modules-bfn/debian/compat create mode 100644 platform/barefoot/sonic-platform-modules-bfn/debian/control create mode 100644 platform/barefoot/sonic-platform-modules-bfn/debian/copyright create mode 100644 platform/barefoot/sonic-platform-modules-bfn/debian/files create mode 100755 platform/barefoot/sonic-platform-modules-bfn/debian/rules create mode 100644 platform/barefoot/sonic-platform-modules-bfn/modules/Makefile create mode 100644 platform/barefoot/sonic-platform-modules-bfn/modules/bf_kdrv.c create mode 100644 platform/barefoot/sonic-platform-modules-bfn/modules/bf_tun.c create mode 100755 platform/barefoot/sonic-platform-modules-bfn/scripts/test diff --git a/.gitmodules b/.gitmodules index c837451c9480..bbd7722d1517 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,15 +1,15 @@ [submodule "sonic-swss-common"] path = src/sonic-swss-common - url = https://github.com/Azure/sonic-swss-common + url = https://github.com/barefootnetworks/sonic-swss-common [submodule "sonic-linux-kernel"] path = src/sonic-linux-kernel url = https://github.com/Azure/sonic-linux-kernel [submodule "sonic-sairedis"] path = src/sonic-sairedis - url = https://github.com/Azure/sonic-sairedis + url = https://github.com/barefootnetworks/sonic-sairedis [submodule "sonic-swss"] path = src/sonic-swss - url = https://github.com/Azure/sonic-swss + url = https://github.com/barefootnetworks/sonic-swss [submodule "src/p4-switch/switch"] path = platform/p4/p4-switch/switch url = https://github.com/krambn/switch diff --git a/device/barefoot/x86_64-accton_wedge100bf_32x-r0/installer.conf b/device/barefoot/x86_64-accton_wedge100bf_32x-r0/installer.conf new file mode 100644 index 000000000000..3714ff053bb0 --- /dev/null +++ b/device/barefoot/x86_64-accton_wedge100bf_32x-r0/installer.conf @@ -0,0 +1 @@ +CONSOLE_SPEED=57600 diff --git a/device/barefoot/x86_64-accton_wedge100bf_32x-r0/minigraph.xml b/device/barefoot/x86_64-accton_wedge100bf_32x-r0/minigraph.xml new file mode 100644 index 000000000000..20637fc43459 --- /dev/null +++ b/device/barefoot/x86_64-accton_wedge100bf_32x-r0/minigraph.xml @@ -0,0 +1,1079 @@ + + + + + + ARISTA01T0 + 10.0.0.33 + switch2 + 10.0.0.32 + 1 + 180 + 60 + + + switch2 + 10.0.0.0 + ARISTA01T2 + 10.0.0.1 + 1 + 180 + 60 + + + ARISTA02T0 + 10.0.0.35 + switch2 + 10.0.0.34 + 1 + 180 + 60 + + + switch2 + 10.0.0.2 + ARISTA02T2 + 10.0.0.3 + 1 + 180 + 60 + + + ARISTA03T0 + 10.0.0.37 + switch2 + 10.0.0.36 + 1 + 180 + 60 + + + switch2 + 10.0.0.4 + ARISTA03T2 + 10.0.0.5 + 1 + 180 + 60 + + + ARISTA04T0 + 10.0.0.39 + switch2 + 10.0.0.38 + 1 + 180 + 60 + + + switch2 + 10.0.0.6 + ARISTA04T2 + 10.0.0.7 + 1 + 180 + 60 + + + ARISTA05T0 + 10.0.0.41 + switch2 + 10.0.0.40 + 1 + 180 + 60 + + + switch2 + 10.0.0.8 + ARISTA05T2 + 10.0.0.9 + 1 + 180 + 60 + + + ARISTA06T0 + 10.0.0.43 + switch2 + 10.0.0.42 + 1 + 180 + 60 + + + switch2 + 10.0.0.10 + ARISTA06T2 + 10.0.0.11 + 1 + 180 + 60 + + + ARISTA07T0 + 10.0.0.45 + switch2 + 10.0.0.44 + 1 + 180 + 60 + + + switch2 + 10.0.0.12 + ARISTA07T2 + 10.0.0.13 + 1 + 180 + 60 + + + ARISTA08T0 + 10.0.0.47 + switch2 + 10.0.0.46 + 1 + 180 + 60 + + + switch2 + 10.0.0.14 + ARISTA08T2 + 10.0.0.15 + 1 + 180 + 60 + + + ARISTA09T0 + 10.0.0.49 + switch2 + 10.0.0.48 + 1 + 180 + 60 + + + switch2 + 10.0.0.16 + ARISTA09T2 + 10.0.0.17 + 1 + 180 + 60 + + + ARISTA10T0 + 10.0.0.51 + switch2 + 10.0.0.50 + 1 + 180 + 60 + + + switch2 + 10.0.0.18 + ARISTA10T2 + 10.0.0.19 + 1 + 180 + 60 + + + ARISTA11T0 + 10.0.0.53 + switch2 + 10.0.0.52 + 1 + 180 + 60 + + + switch2 + 10.0.0.20 + ARISTA11T2 + 10.0.0.21 + 1 + 180 + 60 + + + ARISTA12T0 + 10.0.0.55 + switch2 + 10.0.0.54 + 1 + 180 + 60 + + + switch2 + 10.0.0.22 + ARISTA12T2 + 10.0.0.23 + 1 + 180 + 60 + + + ARISTA13T0 + 10.0.0.57 + switch2 + 10.0.0.56 + 1 + 180 + 60 + + + switch2 + 10.0.0.24 + ARISTA13T2 + 10.0.0.25 + 1 + 180 + 60 + + + ARISTA14T0 + 10.0.0.59 + switch2 + 10.0.0.58 + 1 + 180 + 60 + + + switch2 + 10.0.0.26 + ARISTA14T2 + 10.0.0.27 + 1 + 180 + 60 + + + ARISTA15T0 + 10.0.0.61 + switch2 + 10.0.0.60 + 1 + 180 + 60 + + + switch2 + 10.0.0.28 + ARISTA15T2 + 10.0.0.29 + 1 + 180 + 60 + + + ARISTA16T0 + 10.0.0.63 + switch2 + 10.0.0.62 + 1 + 180 + 60 + + + switch2 + 10.0.0.30 + ARISTA16T2 + 10.0.0.31 + 1 + 180 + 60 + + + + + 65100 + switch2 + + +
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 + + + + + + + + switch2 + + + + + + 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 + switch2 + Ethernet0 + ARISTA01T2 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet4 + ARISTA02T2 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet8 + ARISTA03T2 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet12 + ARISTA04T2 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet16 + ARISTA05T2 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet20 + ARISTA06T2 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet24 + ARISTA07T2 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet28 + ARISTA08T2 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet32 + ARISTA09T2 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet36 + ARISTA10T2 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet40 + ARISTA11T2 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet44 + ARISTA12T2 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet48 + ARISTA13T2 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet52 + ARISTA14T2 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet56 + ARISTA15T2 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet60 + ARISTA16T2 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet64 + ARISTA01T0 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet68 + ARISTA02T0 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet72 + ARISTA03T0 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet76 + ARISTA04T0 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet80 + ARISTA05T0 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet84 + ARISTA06T0 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet88 + ARISTA07T0 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet92 + ARISTA08T0 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet96 + ARISTA09T0 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet100 + ARISTA10T0 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet104 + ARISTA11T0 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet108 + ARISTA12T0 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet112 + ARISTA13T0 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet116 + ARISTA14T0 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet120 + ARISTA15T0 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet124 + ARISTA16T0 + Ethernet1 + + + + + switch2 + montara + + ` + + + + + switch2 + + + 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 + + + + + + + switch2 + montara +
diff --git a/device/barefoot/x86_64-accton_wedge100bf_32x-r0/montara/port_config.ini b/device/barefoot/x86_64-accton_wedge100bf_32x-r0/montara/port_config.ini new file mode 100644 index 000000000000..816bb0e94a70 --- /dev/null +++ b/device/barefoot/x86_64-accton_wedge100bf_32x-r0/montara/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/barefoot/x86_64-accton_wedge100bf_65x-r0/installer.conf b/device/barefoot/x86_64-accton_wedge100bf_65x-r0/installer.conf new file mode 100644 index 000000000000..3714ff053bb0 --- /dev/null +++ b/device/barefoot/x86_64-accton_wedge100bf_65x-r0/installer.conf @@ -0,0 +1 @@ +CONSOLE_SPEED=57600 diff --git a/device/barefoot/x86_64-accton_wedge100bf_65x-r0/mavericks/port_config.ini b/device/barefoot/x86_64-accton_wedge100bf_65x-r0/mavericks/port_config.ini new file mode 100644 index 000000000000..c1001741d28a --- /dev/null +++ b/device/barefoot/x86_64-accton_wedge100bf_65x-r0/mavericks/port_config.ini @@ -0,0 +1,66 @@ +# 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 +Ethernet128 128,129,130,131 +Ethernet132 132,133,134,135 +Ethernet136 136,137,138,139 +Ethernet140 140,141,142,143 +Ethernet144 144,145,146,147 +Ethernet148 148,149,150,151 +Ethernet152 152,153,154,155 +Ethernet156 156,157,158,159 +Ethernet160 160,161,162,163 +Ethernet164 164,165,166,167 +Ethernet168 168,169,170,171 +Ethernet172 172,173,174,175 +Ethernet176 176,177,178,179 +Ethernet180 180,181,182,183 +Ethernet184 184,185,186,187 +Ethernet188 188,189,190,191 +Ethernet192 192,193,194,195 +Ethernet196 196,197,198,199 +Ethernet200 200,201,202,203 +Ethernet204 204,205,206,207 +Ethernet208 208,209,210,211 +Ethernet212 212,213,214,215 +Ethernet216 216,217,218,219 +Ethernet220 220,221,222,223 +Ethernet224 224,225,226,227 +Ethernet228 228,229,230,231 +Ethernet232 232,233,234,235 +Ethernet236 236,237,238,239 +Ethernet240 240,241,242,243 +Ethernet244 244,245,246,247 +Ethernet248 248,249,250,251 +Ethernet252 252,253,254,255 +Ethernet256 256,257,258,259 diff --git a/device/barefoot/x86_64-accton_wedge100bf_65x-r0/minigraph.xml b/device/barefoot/x86_64-accton_wedge100bf_65x-r0/minigraph.xml new file mode 100644 index 000000000000..61f7b9c85a3c --- /dev/null +++ b/device/barefoot/x86_64-accton_wedge100bf_65x-r0/minigraph.xml @@ -0,0 +1,1079 @@ + + + + + + ARISTA01T0 + 10.0.0.33 + switch2 + 10.0.0.32 + 1 + 180 + 60 + + + switch2 + 10.0.0.0 + ARISTA01T2 + 10.0.0.1 + 1 + 180 + 60 + + + ARISTA02T0 + 10.0.0.35 + switch2 + 10.0.0.34 + 1 + 180 + 60 + + + switch2 + 10.0.0.2 + ARISTA02T2 + 10.0.0.3 + 1 + 180 + 60 + + + ARISTA03T0 + 10.0.0.37 + switch2 + 10.0.0.36 + 1 + 180 + 60 + + + switch2 + 10.0.0.4 + ARISTA03T2 + 10.0.0.5 + 1 + 180 + 60 + + + ARISTA04T0 + 10.0.0.39 + switch2 + 10.0.0.38 + 1 + 180 + 60 + + + switch2 + 10.0.0.6 + ARISTA04T2 + 10.0.0.7 + 1 + 180 + 60 + + + ARISTA05T0 + 10.0.0.41 + switch2 + 10.0.0.40 + 1 + 180 + 60 + + + switch2 + 10.0.0.8 + ARISTA05T2 + 10.0.0.9 + 1 + 180 + 60 + + + ARISTA06T0 + 10.0.0.43 + switch2 + 10.0.0.42 + 1 + 180 + 60 + + + switch2 + 10.0.0.10 + ARISTA06T2 + 10.0.0.11 + 1 + 180 + 60 + + + ARISTA07T0 + 10.0.0.45 + switch2 + 10.0.0.44 + 1 + 180 + 60 + + + switch2 + 10.0.0.12 + ARISTA07T2 + 10.0.0.13 + 1 + 180 + 60 + + + ARISTA08T0 + 10.0.0.47 + switch2 + 10.0.0.46 + 1 + 180 + 60 + + + switch2 + 10.0.0.14 + ARISTA08T2 + 10.0.0.15 + 1 + 180 + 60 + + + ARISTA09T0 + 10.0.0.49 + switch2 + 10.0.0.48 + 1 + 180 + 60 + + + switch2 + 10.0.0.16 + ARISTA09T2 + 10.0.0.17 + 1 + 180 + 60 + + + ARISTA10T0 + 10.0.0.51 + switch2 + 10.0.0.50 + 1 + 180 + 60 + + + switch2 + 10.0.0.18 + ARISTA10T2 + 10.0.0.19 + 1 + 180 + 60 + + + ARISTA11T0 + 10.0.0.53 + switch2 + 10.0.0.52 + 1 + 180 + 60 + + + switch2 + 10.0.0.20 + ARISTA11T2 + 10.0.0.21 + 1 + 180 + 60 + + + ARISTA12T0 + 10.0.0.55 + switch2 + 10.0.0.54 + 1 + 180 + 60 + + + switch2 + 10.0.0.22 + ARISTA12T2 + 10.0.0.23 + 1 + 180 + 60 + + + ARISTA13T0 + 10.0.0.57 + switch2 + 10.0.0.56 + 1 + 180 + 60 + + + switch2 + 10.0.0.24 + ARISTA13T2 + 10.0.0.25 + 1 + 180 + 60 + + + ARISTA14T0 + 10.0.0.59 + switch2 + 10.0.0.58 + 1 + 180 + 60 + + + switch2 + 10.0.0.26 + ARISTA14T2 + 10.0.0.27 + 1 + 180 + 60 + + + ARISTA15T0 + 10.0.0.61 + switch2 + 10.0.0.60 + 1 + 180 + 60 + + + switch2 + 10.0.0.28 + ARISTA15T2 + 10.0.0.29 + 1 + 180 + 60 + + + ARISTA16T0 + 10.0.0.63 + switch2 + 10.0.0.62 + 1 + 180 + 60 + + + switch2 + 10.0.0.30 + ARISTA16T2 + 10.0.0.31 + 1 + 180 + 60 + + + + + 65100 + switch2 + + +
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 + + + + + + + + switch2 + + + + + + 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 + switch2 + Ethernet0 + ARISTA01T2 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet4 + ARISTA02T2 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet8 + ARISTA03T2 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet12 + ARISTA04T2 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet16 + ARISTA05T2 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet20 + ARISTA06T2 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet24 + ARISTA07T2 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet28 + ARISTA08T2 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet32 + ARISTA09T2 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet36 + ARISTA10T2 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet40 + ARISTA11T2 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet44 + ARISTA12T2 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet48 + ARISTA13T2 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet52 + ARISTA14T2 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet56 + ARISTA15T2 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet60 + ARISTA16T2 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet64 + ARISTA01T0 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet68 + ARISTA02T0 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet72 + ARISTA03T0 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet76 + ARISTA04T0 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet80 + ARISTA05T0 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet84 + ARISTA06T0 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet88 + ARISTA07T0 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet92 + ARISTA08T0 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet96 + ARISTA09T0 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet100 + ARISTA10T0 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet104 + ARISTA11T0 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet108 + ARISTA12T0 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet112 + ARISTA13T0 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet116 + ARISTA14T0 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet120 + ARISTA15T0 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet124 + ARISTA16T0 + Ethernet1 + + + + + switch2 + mavericks + + ` + + + + + switch2 + + + 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 + + + + + + + switch2 + mavericks +
diff --git a/dockers/docker-bfn-sswsyncd-rpc/Dockerfile b/dockers/docker-bfn-sswsyncd-rpc/Dockerfile new file mode 100644 index 000000000000..4d1b3e49bcda --- /dev/null +++ b/dockers/docker-bfn-sswsyncd-rpc/Dockerfile @@ -0,0 +1,38 @@ +FROM docker-base + +## Make apt-get non-interactive +ENV DEBIAN_FRONTEND=noninteractive + +## Pre-install the fundamental packages +RUN apt-get update \ + && apt-get -y install \ + net-tools + +COPY deps /deps +RUN dpkg_apt() { [ -f $1 ] && { dpkg -i $1 || apt-get -y install -f; } || return 1; }; \ + dpkg_apt /deps/python-tabulate_*.deb \ + && dpkg_apt /deps/applibs_*.deb \ + && dpkg_apt /deps/applibs-dev_*.deb \ + && dpkg_apt /deps/sx-complib_*.deb \ + && dpkg_apt /deps/sxd-libs_*.deb \ + && dpkg_apt /deps/sx-scew_*.deb \ + && dpkg_apt /deps/sx-examples_*.deb \ + && dpkg_apt /deps/sx-gen-utils_*.deb \ + && dpkg_apt /deps/python-sdk-api_*.deb \ + && dpkg_apt /deps/sx-libnl_*.deb \ + && dpkg_apt /deps/iproute2_*.deb \ + && dpkg_apt /deps/libsswsdk_*.deb \ + && dpkg_apt /deps/libthrift-0.9.3_*.deb \ + && dpkg_apt /deps/libthrift-dev_*.deb + +RUN dpkg_apt() { [ -f $1 ] && { dpkg -i $1 || apt-get -y install -f; } || return 1; }; \ + dpkg_apt /deps/mlnx-sai_*.deb \ + && dpkg_apt /deps/sswsyncd-saithrift_*.deb + +## Clean up +RUN apt-get clean -y ; apt-get autoclean -y ; apt-get autoremove -y ; rm -rf /deps + +ENTRYPOINT service rsyslog start \ + && mkdir -p /dev/sxdevs && ( [ -e /dev/sxdevs/sxcdev ] || mknod /dev/sxdevs/sxcdev c 231 193 ) \ + && service sswsyncd start \ + && /bin/bash diff --git a/dockers/docker-bfn-sswsyncd/Dockerfile b/dockers/docker-bfn-sswsyncd/Dockerfile new file mode 100755 index 000000000000..9bb6c71e8729 --- /dev/null +++ b/dockers/docker-bfn-sswsyncd/Dockerfile @@ -0,0 +1,17 @@ +FROM docker-base + +## Make apt-get non-interactive +ENV DEBIAN_FRONTEND=noninteractive + +RUN apt-get update + +## Pre-install the fundamental packages +RUN apt-get update \ + && apt-get -y install \ + net-tools + +COPY deps /deps + +ENTRYPOINT service rsyslog start \ + && sleep 5 && service sswsyncd start \ + && /bin/bash diff --git a/dockers/docker-orchagent-bfn b/dockers/docker-orchagent-bfn new file mode 120000 index 000000000000..8d52609c56e5 --- /dev/null +++ b/dockers/docker-orchagent-bfn @@ -0,0 +1 @@ +docker-orchagent \ No newline at end of file diff --git a/dockers/docker-orchagent/orchagent.sh b/dockers/docker-orchagent/orchagent.sh index f92dfe5fd543..b11a20223035 100755 --- a/dockers/docker-orchagent/orchagent.sh +++ b/dockers/docker-orchagent/orchagent.sh @@ -18,6 +18,8 @@ if [ "$platform" == "broadcom" ]; then ORCHAGENT_ARGS+="-m $MAC_ADDRESS" elif [ "$platform" == "cavium" ]; then ORCHAGENT_ARGS+="-m $MAC_ADDRESS" +elif [ "$ASIC" == "barefoot" ]; then + ORCHAGENT_ARGS+="-m $MAC_ADDRESS" fi exec /usr/bin/orchagent ${ORCHAGENT_ARGS} diff --git a/dockers/docker-saiserver-bfn/Dockerfile b/dockers/docker-saiserver-bfn/Dockerfile new file mode 100755 index 000000000000..427a551e0096 --- /dev/null +++ b/dockers/docker-saiserver-bfn/Dockerfile @@ -0,0 +1,38 @@ +FROM docker-base + +## Make apt-get non-interactive +ENV DEBIAN_FRONTEND=noninteractive + +RUN apt-get update + +COPY ["deps/applibs_*.deb", "/deps/applibs-dev_*.deb", "/deps/sx-complib_*.deb", "/deps/sxd-libs_*.deb", "/deps/sx-scew_*.deb", "/deps/sx-examples_*.deb", "/deps/sx-gen-utils_*.deb", "/deps/python-sdk-api_*.deb", "/deps/iproute2_*.deb", "/deps/mlnx-sai_*.deb", "/deps/libthrift-0.9.3_*.deb", "/deps/libnl-3-200_*.deb", "/deps/libnl-genl-3-200_*.deb", "/deps/libnl-route-3-200_*.deb", "/deps/"] + +RUN dpkg_apt() { [ -f $1 ] && { dpkg -i $1 || apt-get -y install -f; } || return 1; }; \ + dpkg_apt /deps/applibs_*.deb \ + && dpkg_apt /deps/applibs-dev_*.deb \ + && dpkg_apt /deps/sx-complib_*.deb \ + && dpkg_apt /deps/sxd-libs_*.deb \ + && dpkg_apt /deps/sx-scew_*.deb \ + && dpkg_apt /deps/sx-examples_*.deb \ + && dpkg_apt /deps/sx-gen-utils_*.deb \ + && dpkg_apt /deps/python-sdk-api_*.deb \ + && dpkg_apt /deps/iproute2_*.deb \ + && dpkg_apt /deps/mlnx-sai_*.deb \ + && dpkg_apt /deps/libthrift-0.9.3_*.deb \ + && dpkg_apt /deps/libnl-3-200_*.deb \ + && dpkg_apt /deps/libnl-genl-3-200_*.deb \ + && dpkg_apt /deps/libnl-route-3-200_*.deb + +COPY ["deps/saiserver", "start.sh", "/usr/bin/"] + +COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] + +COPY ["profile.ini", "portmap.ini", "/etc/sai/"] + + +## Clean up +RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y +RUN rm -rf /deps + +ENTRYPOINT ["/usr/bin/supervisord"] + diff --git a/dockers/docker-saiserver-bfn/portmap.ini b/dockers/docker-saiserver-bfn/portmap.ini new file mode 100644 index 000000000000..4d3be08ce5f8 --- /dev/null +++ b/dockers/docker-saiserver-bfn/portmap.ini @@ -0,0 +1,33 @@ +# alias lanes +Ethernet1 0,1,2,3 +Ethernet2 4,5,6,7 +Ethernet3 8,9,10,11 +Ethernet4 12,13,14,15 +Ethernet5 16,17,18,19 +Ethernet6 20,21,22,23 +Ethernet7 24,25,26,27 +Ethernet8 28,29,30,31 +Ethernet9 32,33,34,35 +Ethernet10 36,37,38,39 +Ethernet11 40,41,42,43 +Ethernet12 44,45,46,47 +Ethernet13 48,49,50,51 +Ethernet14 52,53,54,55 +Ethernet15 56,57,58,59 +Ethernet16 60,61,62,63 +Ethernet17 64,65,66,67 +Ethernet18 68,69,70,71 +Ethernet19 72,73,74,75 +Ethernet20 76,77,78,79 +Ethernet21 80,81,82,83 +Ethernet22 84,85,86,87 +Ethernet23 88,89,90,91 +Ethernet24 92,93,94,95 +Ethernet25 96,97,98,99 +Ethernet26 100,101,102,103 +Ethernet27 104,105,106,107 +Ethernet28 108,109,110,111 +Ethernet29 112,113,114,115 +Ethernet30 116,117,118,119 +Ethernet31 120,121,122,123 +Ethernet32 124,125,126,127 \ No newline at end of file diff --git a/dockers/docker-saiserver-bfn/profile.ini b/dockers/docker-saiserver-bfn/profile.ini new file mode 100644 index 000000000000..b20b2c6f0e06 --- /dev/null +++ b/dockers/docker-saiserver-bfn/profile.ini @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sai_tofino.xml diff --git a/dockers/docker-saiserver-bfn/sai_tofino.xml b/dockers/docker-saiserver-bfn/sai_tofino.xml new file mode 100644 index 000000000000..139597f9cb07 --- /dev/null +++ b/dockers/docker-saiserver-bfn/sai_tofino.xml @@ -0,0 +1,2 @@ + + diff --git a/dockers/docker-saiserver-bfn/start.sh b/dockers/docker-saiserver-bfn/start.sh new file mode 100755 index 000000000000..57ee5036ded3 --- /dev/null +++ b/dockers/docker-saiserver-bfn/start.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash + +start_mlnx() +{ + [ -e /dev/sxdevs/sxcdev ] || ( mkdir -p /dev/sxdevs && mknod /dev/sxdevs/sxcdev c 231 193 ) +} + + +rm -f /var/run/rsyslogd.pid + +supervisorctl start rsyslogd + +start_mlnx + +supervisorctl start saiserver + diff --git a/dockers/docker-saiserver-bfn/supervisord.conf b/dockers/docker-saiserver-bfn/supervisord.conf new file mode 100644 index 000000000000..e09ac3cbb449 --- /dev/null +++ b/dockers/docker-saiserver-bfn/supervisord.conf @@ -0,0 +1,29 @@ +[supervisord] +logfile_maxbytes=1MB +logfile_backups=2 +nodaemon=true + +[program:start.sh] +command=/usr/bin/start.sh +priority=1 +autostart=true +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog + +[program:rsyslogd] +command=/usr/sbin/rsyslogd -n +priority=2 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog + +[program:saiserver] +command=/usr/bin/saiserver -p /etc/sai/profile.ini -f /etc/sai/portmap.ini +priority=3 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog + diff --git a/files/image_config/interfaces/interfaces.j2 b/files/image_config/interfaces/interfaces.j2 index 2fdd04804ca4..7822858ca096 100644 --- a/files/image_config/interfaces/interfaces.j2 +++ b/files/image_config/interfaces/interfaces.j2 @@ -18,6 +18,11 @@ iface lo {{ 'inet' if prefix | ipv4 else 'inet6' }} static {% endfor %} {% endblock loopback %} {% block mgmt_interface %} +# BMC interface +auto usb0 +iface usb0 inet static + address 192.168.0.2 + netmask 255.255.255.0 # The management network interface auto eth0 {% if MGMT_INTERFACE %} diff --git a/platform/barefoot/bfn-sai.mk b/platform/barefoot/bfn-sai.mk new file mode 100644 index 000000000000..4f27a7ae18c4 --- /dev/null +++ b/platform/barefoot/bfn-sai.mk @@ -0,0 +1,6 @@ +BFN_SAI = bfnsdk_1.0.0_amd64.deb +$(BFN_SAI)_URL = "https://www.dropbox.com/s/4ljk6hzw82rudsr/bfnsdk_1.0.0_amd64.deb?dl=0" +# $(BFN_SAI_DEV)_URL = "https://www.dropbox.com/s/4ljk6hzw82rudsr/bfnsdk_1.0.0_amd64.deb?dl=0" + +SONIC_ONLINE_DEBS += $(BFN_SAI) # $(BFN_SAI_DEV) +$(BFN_SAI_DEV)_DEPENDS += $(BFN_SAI) diff --git a/platform/barefoot/docker-orchagent-bfn.mk b/platform/barefoot/docker-orchagent-bfn.mk new file mode 100644 index 000000000000..ac338f2ba7e6 --- /dev/null +++ b/platform/barefoot/docker-orchagent-bfn.mk @@ -0,0 +1,18 @@ +# docker image for orchagent + +DOCKER_ORCHAGENT_BFN = docker-orchagent-bfn.gz +$(DOCKER_ORCHAGENT_BFN)_PATH = $(DOCKERS_PATH)/docker-orchagent +$(DOCKER_ORCHAGENT_BFN)_DEPENDS += $(SWSS) $(REDIS_TOOLS) +$(DOCKER_ORCHAGENT_BFN)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE) +SONIC_DOCKER_IMAGES += $(DOCKER_ORCHAGENT_BFN) +SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_ORCHAGENT_BFN) + +$(DOCKER_ORCHAGENT_BFN)_CONTAINER_NAME = swss +$(DOCKER_ORCHAGENT_BFN)_RUN_OPT += --net=host --privileged -t +$(DOCKER_ORCHAGENT_BFN)_RUN_OPT += -v /etc/network/interfaces:/etc/network/interfaces:ro +$(DOCKER_ORCHAGENT_BFN)_RUN_OPT += -v /etc/network/interfaces.d/:/etc/network/interfaces.d/:ro +$(DOCKER_ORCHAGENT_BFN)_RUN_OPT += -v /host/machine.conf:/host/machine.conf:ro +$(DOCKER_ORCHAGENT_BFN)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro +$(DOCKER_ORCHAGENT_BFN)_RUN_OPT += -v /var/log/swss:/var/log/swss:rw + +$(DOCKER_ORCHAGENT_BFN)_BASE_IMAGE_FILES += swssloglevel:/usr/bin/swssloglevel diff --git a/platform/barefoot/docker-ptf-bfn.mk b/platform/barefoot/docker-ptf-bfn.mk new file mode 100644 index 000000000000..573e9cd9cffa --- /dev/null +++ b/platform/barefoot/docker-ptf-bfn.mk @@ -0,0 +1,5 @@ +# docker image for docker-ptf + +DOCKER_PTF_BFN = docker-ptf-bfn.gz +$(DOCKER_PTF_BFN)_PATH = $(DOCKERS_PATH)/docker-ptf-saithrift +$(DOCKER_PTF_BFN)_LOAD_DOCKERS += $(DOCKER_PTF) diff --git a/platform/barefoot/docker-syncd-bfn-rpc.mk b/platform/barefoot/docker-syncd-bfn-rpc.mk new file mode 100644 index 000000000000..61f5570c1612 --- /dev/null +++ b/platform/barefoot/docker-syncd-bfn-rpc.mk @@ -0,0 +1,15 @@ +# docker image for syncd with rpc + +DOCKER_SYNCD_BFN_RPC = docker-syncd-bfn-rpc.gz +$(DOCKER_SYNCD_BFN_RPC)_PATH = $(PLATFORM_PATH)/docker-syncd-bfn-rpc +$(DOCKER_SYNCD_BFN_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) +$(DOCKER_SYNCD_BFN_RPC)_LOAD_DOCKERS += $(DOCKER_SYNCD_BFN) +SONIC_DOCKER_IMAGES += $(DOCKER_SYNCD_BFN_RPC) +ifeq ($(ENABLE_SYNCD_RPC),y) +SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_SYNCD_BFN_RPC) +endif + +$(DOCKER_SYNCD_BFN_RPC)_CONTAINER_NAME = syncd +$(DOCKER_SYNCD_BFN_RPC)_RUN_OPT += --net=host --privileged -t +$(DOCKER_SYNCD_BFN_RPC)_RUN_OPT += -v /host/machine.conf:/etc/machine.conf +$(DOCKER_SYNCD_BFN_RPC)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro diff --git a/platform/barefoot/docker-syncd-bfn-rpc/Dockerfile.j2 b/platform/barefoot/docker-syncd-bfn-rpc/Dockerfile.j2 new file mode 100644 index 000000000000..590f80aacde3 --- /dev/null +++ b/platform/barefoot/docker-syncd-bfn-rpc/Dockerfile.j2 @@ -0,0 +1,52 @@ +FROM docker-syncd-bfn + +## Make apt-get non-interactive +ENV DEBIAN_FRONTEND=noninteractive + +COPY \ +{% for deb in docker_syncd_bfn.split(' ') -%} +debs/{{ deb }}{{' '}} +{%- endfor -%} +debs/ + +RUN dpkg -P syncd + +RUN dpkg_apt() { [ -f $1 ] && { dpkg -i $1 || apt-get -y install -f; } || return 1; } ; \ +{% for deb in docker_syncd_bfn.split(' ') -%} +dpkg_apt debs/{{ deb }}{{'; '}} +{%- endfor %} + +## Pre-install the fundamental packages +RUN apt-get update \ + && apt-get -y install \ + net-tools \ + python-pip \ + build-essential \ + libssl-dev \ + libffi-dev \ + python-dev \ + wget \ + cmake \ + && wget https://github.com/nanomsg/nanomsg/archive/1.0.0.tar.gz \ + && tar xvfz 1.0.0.tar.gz \ + && cd nanomsg-1.0.0 \ + && mkdir -p build \ + && cmake . \ + && make install \ + && ldconfig \ + && cd .. \ + && rm -fr nanomsg-1.0.0 \ + && rm -f 1.0.0.tar.gz \ + && pip install cffi==1.7.0 \ + && pip install --upgrade cffi==1.7.0 \ + && pip install nnpy \ + && mkdir -p /opt \ + && cd /opt \ + && wget https://raw.githubusercontent.com/p4lang/ptf/master/ptf_nn/ptf_nn_agent.py \ + && apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y \ + && rm -rf /root/deps + +COPY ["ptf_nn_agent.conf", "/etc/supervisor/conf.d/"] + +ENTRYPOINT ["/usr/bin/supervisord"] + diff --git a/platform/barefoot/docker-syncd-bfn-rpc/ptf_nn_agent.conf b/platform/barefoot/docker-syncd-bfn-rpc/ptf_nn_agent.conf new file mode 100644 index 000000000000..fa1ed0eb1622 --- /dev/null +++ b/platform/barefoot/docker-syncd-bfn-rpc/ptf_nn_agent.conf @@ -0,0 +1,10 @@ +[program:ptf_nn_agent] +command=/usr/bin/python /opt/ptf_nn_agent.py --device-socket 1@tcp://0.0.0.0:10900 -i 1-3@Ethernet12 --set-iface-rcv-buffer=109430400 +process_name=ptf_nn_agent +stdout_logfile=/tmp/ptf_nn_agent.out.log +stderr_logfile=/tmp/ptf_nn_agent.err.log +redirect_stderr=false +autostart=true +autorestart=true +startsecs=1 +numprocs=1 diff --git a/platform/barefoot/docker-syncd-bfn.mk b/platform/barefoot/docker-syncd-bfn.mk new file mode 100644 index 000000000000..22bb10763e75 --- /dev/null +++ b/platform/barefoot/docker-syncd-bfn.mk @@ -0,0 +1,15 @@ +# docker image for syncd + +DOCKER_SYNCD_BFN = docker-syncd-bfn.gz +$(DOCKER_SYNCD_BFN)_PATH = $(PLATFORM_PATH)/docker-syncd-bfn +$(DOCKER_SYNCD_BFN)_DEPENDS += $(SYNCD) +$(DOCKER_SYNCD_BFN)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE) +SONIC_DOCKER_IMAGES += $(DOCKER_SYNCD_BFN) +ifneq ($(ENABLE_SYNCD_RPC),y) +SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_SYNCD_BFN) +endif + +$(DOCKER_SYNCD_BFN)_CONTAINER_NAME = syncd +$(DOCKER_SYNCD_BFN)_RUN_OPT += --net=host --privileged -t +$(DOCKER_SYNCD_BFN)_RUN_OPT += -v /host/machine.conf:/etc/machine.conf +$(DOCKER_SYNCD_BFN)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro diff --git a/platform/barefoot/docker-syncd-bfn/Dockerfile.j2 b/platform/barefoot/docker-syncd-bfn/Dockerfile.j2 new file mode 100755 index 000000000000..54e55e110890 --- /dev/null +++ b/platform/barefoot/docker-syncd-bfn/Dockerfile.j2 @@ -0,0 +1,29 @@ +FROM docker-config-engine + +## Make apt-get non-interactive +ENV DEBIAN_FRONTEND=noninteractive + +RUN apt-get update + +COPY \ +{% for deb in docker_syncd_bfn_debs.split(' ') -%} +debs/{{ deb }}{{' '}} +{%- endfor -%} +debs/ + +RUN apt-get install -y libxml2 libpcap-dev libusb-1.0-0-dev libcurl3 libcurl4-gnutls-dev + +RUN dpkg -i \ +{% for deb in docker_syncd_bfn_debs.split(' ') -%} +debs/{{ deb }}{{' '}} +{%- endfor %} + +COPY ["start.sh", "/usr/bin/"] +COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] + +## Clean up +RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y +RUN rm -rf /debs + +ENTRYPOINT ["/usr/bin/supervisord"] + diff --git a/platform/barefoot/docker-syncd-bfn/start.sh b/platform/barefoot/docker-syncd-bfn/start.sh new file mode 100755 index 000000000000..1a39db4a9d83 --- /dev/null +++ b/platform/barefoot/docker-syncd-bfn/start.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +rm -f /var/run/rsyslogd.pid + +supervisorctl start rsyslogd + +. /opt/bfn/install/bin/dma_setup.sh +# . /opt/bfn/install/bin/bf_kdrv_mod_load /opt/bfn/install +LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/bfn/install/lib supervisorctl start syncd diff --git a/platform/barefoot/docker-syncd-bfn/supervisord.conf b/platform/barefoot/docker-syncd-bfn/supervisord.conf new file mode 100644 index 000000000000..1e015fef931f --- /dev/null +++ b/platform/barefoot/docker-syncd-bfn/supervisord.conf @@ -0,0 +1,29 @@ +[supervisord] +logfile_maxbytes=1MB +logfile_backups=2 +nodaemon=true + +[program:start.sh] +command=/usr/bin/start.sh +priority=1 +autostart=true +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog + +[program:rsyslogd] +command=/usr/sbin/rsyslogd -n +priority=2 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog + +[program:syncd] +command=/usr/bin/syncd_start.sh +priority=3 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog + diff --git a/platform/barefoot/libsaithrift-dev.mk b/platform/barefoot/libsaithrift-dev.mk new file mode 100644 index 000000000000..c9c8cbb3adca --- /dev/null +++ b/platform/barefoot/libsaithrift-dev.mk @@ -0,0 +1,7 @@ +# libsaithrift-dev package + +LIBSAITHRIFT_DEV_BFN = libsaithrift-dev_0.9.4_amd64.deb +$(LIBSAITHRIFT_DEV_BFN)_SRC_PATH = $(SRC_PATH)/SAI +$(LIBSAITHRIFT_DEV_BFN)_DEPENDS += $(LIBTHRIFT) $(LIBTHRIFT_DEV) $(THRIFT_COMPILER) $(BFN_SAI) $(BFN_SAI_DEV) +$(LIBSAITHRIFT_DEV_BFN)_RDEPENDS += $(LIBTHRIFT) $(BFN_SAI) +#SONIC_DPKG_DEBS += $(LIBSAITHRIFT_DEV_BFN) diff --git a/platform/barefoot/one-image.mk b/platform/barefoot/one-image.mk new file mode 100644 index 000000000000..52cc9ba369aa --- /dev/null +++ b/platform/barefoot/one-image.mk @@ -0,0 +1,11 @@ +# sonic one image installer + +SONIC_ONE_IMAGE = sonic-barefoot.bin +$(SONIC_ONE_IMAGE)_MACHINE = barefoot +$(SONIC_ONE_IMAGE)_IMAGE_TYPE = onie +$(SONIC_ONE_IMAGE)_INSTALLS += $(BFN_PLATFORM_MODULE) +$(SONIC_ONE_IMAGE)_INSTALLS += $(BFN_MONTARA_PLATFORM_MODULE) +$(SONIC_ONE_IMAGE)_DEPENDS += $(BFN_PLATFORM_MODULE) +$(SONIC_ONE_IMAGE)_DEPENDS += $(BFN_MONTARA_PLATFORM_MODULE) +$(SONIC_ONE_IMAGE)_DOCKERS += $(SONIC_INSTALL_DOCKER_IMAGES) +SONIC_INSTALLERS += $(SONIC_ONE_IMAGE) diff --git a/platform/barefoot/platform-modules-bfn-montara.mk b/platform/barefoot/platform-modules-bfn-montara.mk new file mode 100644 index 000000000000..113faf201e41 --- /dev/null +++ b/platform/barefoot/platform-modules-bfn-montara.mk @@ -0,0 +1,11 @@ +# BFN Platform modules + +BFN_MONTARA_PLATFORM_MODULE_VERSION = 1.0 + +export BFN_MONTARA_PLATFORM_MODULE_VERSION + +BFN_MONTARA_PLATFORM_MODULE = platform-modules-bfn-montara_$(BFN_MONTARA_PLATFORM_MODULE_VERSION)_amd64.deb +$(BFN_MONTARA_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-bfn-montara +$(BFN_MONTARA_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) +$(BFN_MONTARA_PLATFORM_MODULE)_PLATFORM = x86_64-accton_wedge100bf_32x-r0 +SONIC_DPKG_DEBS += $(BFN_MONTARA_PLATFORM_MODULE) diff --git a/platform/barefoot/platform-modules-bfn.mk b/platform/barefoot/platform-modules-bfn.mk new file mode 100644 index 000000000000..3f76e94aa0b2 --- /dev/null +++ b/platform/barefoot/platform-modules-bfn.mk @@ -0,0 +1,11 @@ +# BFN Platform modules + +BFN_PLATFORM_MODULE_VERSION = 1.0 + +export BFN_PLATFORM_MODULE_VERSION + +BFN_PLATFORM_MODULE = platform-modules-bfn_$(BFN_PLATFORM_MODULE_VERSION)_amd64.deb +$(BFN_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-bfn +$(BFN_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) +$(BFN_PLATFORM_MODULE)_PLATFORM = x86_64-accton_wedge100bf_65x-r0 +SONIC_DPKG_DEBS += $(BFN_PLATFORM_MODULE) diff --git a/platform/barefoot/platform.conf b/platform/barefoot/platform.conf new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/platform/barefoot/python-saithrift.mk b/platform/barefoot/python-saithrift.mk new file mode 100644 index 000000000000..ba4846402fb8 --- /dev/null +++ b/platform/barefoot/python-saithrift.mk @@ -0,0 +1,6 @@ +# python-saithrift package + +PYTHON_SAITHRIFT_BFN = python-saithrift_0.9.4_amd64.deb +$(PYTHON_SAITHRIFT_BFN)_SRC_PATH = $(SRC_PATH)/SAI +$(PYTHON_SAITHRIFT_BFN)_DEPENDS += $(BFN_SAI_DEV) $(BFN_SAI) $(THRIFT_COMPILER) $(PYTHON_THRIFT) $(LIBTHRIFT_DEV) +#SONIC_DPKG_DEBS += $(PYTHON_SAITHRIFT_BFN) diff --git a/platform/barefoot/rules.mk b/platform/barefoot/rules.mk new file mode 100644 index 000000000000..507e6b7daeea --- /dev/null +++ b/platform/barefoot/rules.mk @@ -0,0 +1,19 @@ +include $(PLATFORM_PATH)/platform-modules-bfn.mk +include $(PLATFORM_PATH)/platform-modules-bfn-montara.mk +include $(PLATFORM_PATH)/bfn-sai.mk +include $(PLATFORM_PATH)/docker-syncd-bfn.mk +include $(PLATFORM_PATH)/docker-syncd-bfn-rpc.mk +include $(PLATFORM_PATH)/docker-orchagent-bfn.mk +include $(PLATFORM_PATH)/one-image.mk +include $(PLATFORM_PATH)/libsaithrift-dev.mk +include $(PLATFORM_PATH)/python-saithrift.mk +include $(PLATFORM_PATH)/docker-ptf-bfn.mk + +SONIC_ALL += $(SONIC_ONE_IMAGE) \ + $(DOCKER_FPM) + +# Inject sai into sairedis +$(LIBSAIREDIS)_DEPENDS += $(BFN_SAI) #$(LIBSAITHRIFT_DEV_BFN) + +# Runtime dependency on sai is set only for syncd +$(SYNCD)_RDEPENDS += $(BFN_SAI) diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/LICENSE b/platform/barefoot/sonic-platform-modules-bfn-montara/LICENSE new file mode 100644 index 000000000000..676cdeec726b --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/LICENSE @@ -0,0 +1,15 @@ +Copyright (C) 2016 Microsoft, 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 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/barefoot/sonic-platform-modules-bfn-montara/MAINTAINERS b/platform/barefoot/sonic-platform-modules-bfn-montara/MAINTAINERS new file mode 100644 index 000000000000..05b0cea082c7 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/MAINTAINERS @@ -0,0 +1,7 @@ +# This file describes the maintainers for sonic-platform-modules-bfn +# See the SONiC project governance document for more information + +Name = "Daxay" +Email = "support@barefootnetworks.com" +Github = barefootnetworks +Mailinglist = sonicproject@googlegroups.com diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/README.md b/platform/barefoot/sonic-platform-modules-bfn-montara/README.md new file mode 100644 index 000000000000..5dc055a1d9c3 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/README.md @@ -0,0 +1,2 @@ +# sonic-platform-modules-bfn +Device drivers for support of BFN platform for the SONiC project diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/debian/changelog b/platform/barefoot/sonic-platform-modules-bfn-montara/debian/changelog new file mode 100644 index 000000000000..070927fd784b --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/debian/changelog @@ -0,0 +1,5 @@ +platform-modules-bfn-montara (1.0) unstable; urgency=low + + * Initial release + + -- Shuotian Cheng Mon, 11 Nov 2015 11:11:11 -0800 diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/debian/compat b/platform/barefoot/sonic-platform-modules-bfn-montara/debian/compat new file mode 100644 index 000000000000..45a4fb75db86 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/debian/compat @@ -0,0 +1 @@ +8 diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/debian/control b/platform/barefoot/sonic-platform-modules-bfn-montara/debian/control new file mode 100644 index 000000000000..1281dffd3f4d --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/debian/control @@ -0,0 +1,12 @@ +Source: platform-modules-bfn-montara +Section: main +Priority: extra +Maintainer: Shuotian Cheng +Build-Depends: debhelper (>= 8.0.0), bzip2 +Standards-Version: 3.9.3 + +Package: platform-modules-bfn-montara +Architecture: amd64 +Depends: linux-image-3.16.0-4-amd64 +Description: kernel modules for platform devices such as fan, led, sfp + diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/debian/copyright b/platform/barefoot/sonic-platform-modules-bfn-montara/debian/copyright new file mode 100644 index 000000000000..ade42b7aa75a --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/debian/copyright @@ -0,0 +1,15 @@ +Provides linux kernel driver for BF PCIe devices + +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/barefoot/sonic-platform-modules-bfn-montara/debian/files b/platform/barefoot/sonic-platform-modules-bfn-montara/debian/files new file mode 100644 index 000000000000..73e471552221 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/debian/files @@ -0,0 +1 @@ +platform-modules-bfn-montara_1.0_amd64.deb main extra diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/debian/rules b/platform/barefoot/sonic-platform-modules-bfn-montara/debian/rules new file mode 100755 index 000000000000..e48edc304904 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/debian/rules @@ -0,0 +1,32 @@ +#!/usr/bin/make -f + +export INSTALL_MOD_DIR:=extra + +PACKAGE_NAME := platform-modules-bfn-montara +KVERSION ?= $(shell uname -r) +KERNEL_SRC := /lib/modules/$(KVERSION) +MODULE_SRC := $(shell pwd)/modules +SCRIPT_SRC := $(shell pwd)/scripts + +%: + dh $@ + +override_dh_auto_build: + make -C $(KERNEL_SRC)/build M=$(MODULE_SRC) + +override_dh_auto_install: + dh_installdirs -p$(PACKAGE_NAME) $(KERNEL_SRC)/$(INSTALL_MOD_DIR) + cp $(MODULE_SRC)/*.ko debian/$(PACKAGE_NAME)/$(KERNEL_SRC)/$(INSTALL_MOD_DIR) + dh_installdirs -p$(PACKAGE_NAME) usr/local/bin + cp -r $(SCRIPT_SRC)/* debian/$(PACKAGE_NAME)/usr/local/bin + +override_dh_usrlocal: + +override_dh_pysupport: + +override_dh_clean: + dh_clean + rm -f $(MODULE_SRC)/*.o $(MODULE_SRC)/*.ko $(MODULE_SRC)/*.mod.c $(MODULE_SRC)/.*.cmd + rm -f $(MODULE_SRC)/Module.markers $(MODULE_SRC)/Module.symvers $(MODULE_SRC)/modules.order + rm -rf $(MODULE_SRC)/.tmp_versions + diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/modules/Makefile b/platform/barefoot/sonic-platform-modules-bfn-montara/modules/Makefile new file mode 120000 index 000000000000..d394585dd286 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/modules/Makefile @@ -0,0 +1 @@ +../../sonic-platform-modules-bfn/modules/Makefile \ No newline at end of file diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/modules/bf_kdrv.c b/platform/barefoot/sonic-platform-modules-bfn-montara/modules/bf_kdrv.c new file mode 120000 index 000000000000..959d811823c0 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/modules/bf_kdrv.c @@ -0,0 +1 @@ +../../sonic-platform-modules-bfn/modules/bf_kdrv.c \ No newline at end of file diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/modules/bf_tun.c b/platform/barefoot/sonic-platform-modules-bfn-montara/modules/bf_tun.c new file mode 120000 index 000000000000..ea380c3075a7 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/modules/bf_tun.c @@ -0,0 +1 @@ +../../sonic-platform-modules-bfn/modules/bf_tun.c \ No newline at end of file diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/scripts/test b/platform/barefoot/sonic-platform-modules-bfn-montara/scripts/test new file mode 100755 index 000000000000..38327722c91f --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/scripts/test @@ -0,0 +1 @@ +echo "test" diff --git a/platform/barefoot/sonic-platform-modules-bfn/LICENSE b/platform/barefoot/sonic-platform-modules-bfn/LICENSE new file mode 100644 index 000000000000..676cdeec726b --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn/LICENSE @@ -0,0 +1,15 @@ +Copyright (C) 2016 Microsoft, 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 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/barefoot/sonic-platform-modules-bfn/MAINTAINERS b/platform/barefoot/sonic-platform-modules-bfn/MAINTAINERS new file mode 100644 index 000000000000..05b0cea082c7 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn/MAINTAINERS @@ -0,0 +1,7 @@ +# This file describes the maintainers for sonic-platform-modules-bfn +# See the SONiC project governance document for more information + +Name = "Daxay" +Email = "support@barefootnetworks.com" +Github = barefootnetworks +Mailinglist = sonicproject@googlegroups.com diff --git a/platform/barefoot/sonic-platform-modules-bfn/README.md b/platform/barefoot/sonic-platform-modules-bfn/README.md new file mode 100644 index 000000000000..5dc055a1d9c3 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn/README.md @@ -0,0 +1,2 @@ +# sonic-platform-modules-bfn +Device drivers for support of BFN platform for the SONiC project diff --git a/platform/barefoot/sonic-platform-modules-bfn/debian/changelog b/platform/barefoot/sonic-platform-modules-bfn/debian/changelog new file mode 100644 index 000000000000..47b18ef78fef --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn/debian/changelog @@ -0,0 +1,5 @@ +platform-modules-bfn (1.0) unstable; urgency=low + + * Initial release + + -- Shuotian Cheng Mon, 11 Nov 2015 11:11:11 -0800 diff --git a/platform/barefoot/sonic-platform-modules-bfn/debian/compat b/platform/barefoot/sonic-platform-modules-bfn/debian/compat new file mode 100644 index 000000000000..45a4fb75db86 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn/debian/compat @@ -0,0 +1 @@ +8 diff --git a/platform/barefoot/sonic-platform-modules-bfn/debian/control b/platform/barefoot/sonic-platform-modules-bfn/debian/control new file mode 100644 index 000000000000..5bdcd7acfcd7 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn/debian/control @@ -0,0 +1,12 @@ +Source: platform-modules-bfn +Section: main +Priority: extra +Maintainer: Shuotian Cheng +Build-Depends: debhelper (>= 8.0.0), bzip2 +Standards-Version: 3.9.3 + +Package: platform-modules-bfn +Architecture: amd64 +Depends: linux-image-3.16.0-4-amd64 +Description: kernel modules for platform devices such as fan, led, sfp + diff --git a/platform/barefoot/sonic-platform-modules-bfn/debian/copyright b/platform/barefoot/sonic-platform-modules-bfn/debian/copyright new file mode 100644 index 000000000000..ade42b7aa75a --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn/debian/copyright @@ -0,0 +1,15 @@ +Provides linux kernel driver for BF PCIe devices + +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/barefoot/sonic-platform-modules-bfn/debian/files b/platform/barefoot/sonic-platform-modules-bfn/debian/files new file mode 100644 index 000000000000..1cfb92c60ae1 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn/debian/files @@ -0,0 +1 @@ +platform-modules-bfn_1.0_amd64.deb main extra diff --git a/platform/barefoot/sonic-platform-modules-bfn/debian/rules b/platform/barefoot/sonic-platform-modules-bfn/debian/rules new file mode 100755 index 000000000000..73aa5d84da0b --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn/debian/rules @@ -0,0 +1,32 @@ +#!/usr/bin/make -f + +export INSTALL_MOD_DIR:=extra + +PACKAGE_NAME := platform-modules-bfn +KVERSION ?= $(shell uname -r) +KERNEL_SRC := /lib/modules/$(KVERSION) +MODULE_SRC := $(shell pwd)/modules +SCRIPT_SRC := $(shell pwd)/scripts + +%: + dh $@ + +override_dh_auto_build: + make -C $(KERNEL_SRC)/build M=$(MODULE_SRC) + +override_dh_auto_install: + dh_installdirs -p$(PACKAGE_NAME) $(KERNEL_SRC)/$(INSTALL_MOD_DIR) + cp $(MODULE_SRC)/*.ko debian/$(PACKAGE_NAME)/$(KERNEL_SRC)/$(INSTALL_MOD_DIR) + dh_installdirs -p$(PACKAGE_NAME) usr/local/bin + cp -r $(SCRIPT_SRC)/* debian/$(PACKAGE_NAME)/usr/local/bin + +override_dh_usrlocal: + +override_dh_pysupport: + +override_dh_clean: + dh_clean + rm -f $(MODULE_SRC)/*.o $(MODULE_SRC)/*.ko $(MODULE_SRC)/*.mod.c $(MODULE_SRC)/.*.cmd + rm -f $(MODULE_SRC)/Module.markers $(MODULE_SRC)/Module.symvers $(MODULE_SRC)/modules.order + rm -rf $(MODULE_SRC)/.tmp_versions + diff --git a/platform/barefoot/sonic-platform-modules-bfn/modules/Makefile b/platform/barefoot/sonic-platform-modules-bfn/modules/Makefile new file mode 100644 index 000000000000..d180b29f6ae2 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn/modules/Makefile @@ -0,0 +1,2 @@ +obj-m := bf_kdrv.o +obj-m += bf_tun.o diff --git a/platform/barefoot/sonic-platform-modules-bfn/modules/bf_kdrv.c b/platform/barefoot/sonic-platform-modules-bfn/modules/bf_kdrv.c new file mode 100644 index 000000000000..f486a4164470 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn/modules/bf_kdrv.c @@ -0,0 +1,1152 @@ +/******************************************************************************* + * BAREFOOT NETWORKS CONFIDENTIAL & PROPRIETARY + * + * Copyright (c) 2015-2016 Barefoot Networks, Inc. + + * All Rights Reserved. + * + * NOTICE: All information contained herein is, and remains the property of + * Barefoot Networks, Inc. and its suppliers, if any. The intellectual and + * technical concepts contained herein are proprietary to Barefoot Networks, + * Inc. + * and its suppliers and may be covered by U.S. and Foreign Patents, patents in + * process, and are protected by trade secret or copyright law. + * Dissemination of this information or reproduction of this material is + * strictly forbidden unless prior written permission is obtained from + * Barefoot Networks, Inc. + * + * No warranty, explicit or implicit is provided, unless granted under a + * written agreement with Barefoot Networks, Inc. + * + * $Id: $ + * + ******************************************************************************/ +/** + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2015 Barefoot Networks. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * 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... + * + **/ + +/* bf_drv kernel module + * + * This is kernel mode driver for Tofino chip. + * Provides user space mmap service and user space "wait for interrupt" + * and "enable interrupt" services. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 16, 0) +//#error unsupported linux kernel version +#endif + +/* TBD: Need to build with CONFIG_PCI_MSI */ +extern int pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec); +extern int pci_enable_msix_range(struct pci_dev *dev, struct msix_entry *entries, int minvec, int maxvec); + +#define PCI_VENDOR_ID_BF 0x1d1c +#define TOFINO_DEV_ID 1 + +#ifndef PCI_MSIX_ENTRY_SIZE +#define PCI_MSIX_ENTRY_SIZE 16 +#define PCI_MSIX_ENTRY_LOWER_ADDR 0 +#define PCI_MSIX_ENTRY_UPPER_ADDR 4 +#define PCI_MSIX_ENTRY_DATA 8 +#define PCI_MSIX_ENTRY_VECTOR_CTRL 12 +#define PCI_MSIX_ENTRY_CTRL_MASKBIT 1 +#endif + +#define BF_CLASS_NAME "bf" +#define BF_MAX_DEVICE_CNT 256 +#define BF_INTR_MODE_NONE_NAME "none" +#define BF_INTR_MODE_LEGACY_NAME "legacy" +#define BF_INTR_MODE_MSI_NAME "msi" +#define BF_INTR_MODE_MSIX_NAME "msix" +#define BF_MAX_BAR_MAPS 6 +#define BF_MSIX_ENTRY_CNT 128 /* TBD make it 512 */ +#define BF_MSI_ENTRY_CNT 2 + +/* interrupt mode */ +enum bf_intr_mode { + BF_INTR_MODE_NONE = 0, + BF_INTR_MODE_LEGACY, + BF_INTR_MODE_MSI, + BF_INTR_MODE_MSIX +}; + +/* device memory */ +struct bf_dev_mem { + const char *name; + phys_addr_t addr; + resource_size_t size; + void __iomem *internal_addr; +}; + +/* device information */ +struct bf_dev_info { + struct module *owner; + struct device *dev; + int minor; + atomic_t event[BF_MSIX_ENTRY_CNT]; + struct fasync_struct *async_queue; + wait_queue_head_t wait; + const char *version; + struct bf_dev_mem mem[BF_MAX_BAR_MAPS]; + struct msix_entry *msix_entries; + long irq; /* first irq vector */ + int num_irq; /* number of irq vectors */ + unsigned long irq_flags;/* sharable ?? */ + int pci_error_state; /* was there a pci bus error */ +}; + +/* cookie to be passed to IRQ handler, useful especially with MSIX */ +struct bf_int_vector { + struct bf_pci_dev *bf_dev; + int int_vec_offset; +}; + + +/** + * A structure describing the private information for a BF pcie device. + */ +struct bf_pci_dev { + struct bf_dev_info info; + struct pci_dev *pdev; + struct cdev cdev; + enum bf_intr_mode mode; + u8 instance; + char name[16]; + struct bf_int_vector bf_int_vec[BF_MSIX_ENTRY_CNT]; +}; + +static int bf_major; +static int bf_minor[BF_MAX_DEVICE_CNT] = {0}; +static struct class *bf_class = NULL; +static char *intr_mode = NULL; +static enum bf_intr_mode bf_intr_mode_default = BF_INTR_MODE_MSI; +static spinlock_t bf_nonisr_lock; + +/* a pool of minor numbers is maintained */ +/* return the first available minor number */ +static int bf_get_next_minor_no(int *minor) +{ + int i; + + spin_lock(&bf_nonisr_lock); + for(i = 0; i < BF_MAX_DEVICE_CNT; i++) { + if (bf_minor[i] == 0) { + *minor = i; + bf_minor[i] = 1; /* mark it as taken */ + spin_unlock(&bf_nonisr_lock); + return 0; + } + } + *minor = -1; + spin_unlock(&bf_nonisr_lock); + return -1; +} + +/* return a minor number back to the pool for recycling */ +static int bf_return_minor_no(int minor) +{ + int err; + + spin_lock(&bf_nonisr_lock); + if (bf_minor[minor] == 0) { /* was already returned */ + err = -1; /* don't change anything, but return error */ + } else { + bf_minor[minor] = 0; /* mark it as available */ + err = 0; + } + spin_unlock(&bf_nonisr_lock); + return err; +} + +static inline struct bf_pci_dev *bf_get_pci_dev(struct bf_dev_info *info) +{ + return container_of(info, struct bf_pci_dev, info); +} + +/* + * It masks the msix on/off of generating MSI-X messages. + */ +static void +bf_msix_mask_irq(struct msi_desc *desc, int32_t state) +{ + u32 mask_bits = desc->masked; + unsigned offset = desc->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE + + PCI_MSIX_ENTRY_VECTOR_CTRL; + + if (state != 0) + mask_bits &= ~PCI_MSIX_ENTRY_CTRL_MASKBIT; + else + mask_bits |= PCI_MSIX_ENTRY_CTRL_MASKBIT; + + if (mask_bits != desc->masked) { + writel(mask_bits, desc->mask_base + offset); + readl(desc->mask_base); + desc->masked = mask_bits; + } +} + +/** + * irqcontrol can be used to disable/enable interrupt from user space processes. + * + * @param bf_dev + * pointer to bf_pci_dev + * @param irq_state + * state value. 1 to enable interrupt, 0 to disable interrupt. + * + * @return + * - On success, 0. + * - On failure, a negative value. + */ +static int +bf_pci_irqcontrol(struct bf_pci_dev *bfdev, s32 irq_state) +{ + struct pci_dev *pdev = bfdev->pdev; + + pci_cfg_access_lock(pdev); + if (bfdev->mode == BF_INTR_MODE_LEGACY) + pci_intx(pdev, !!irq_state); + + else if (bfdev->mode == BF_INTR_MODE_MSIX) { + struct msi_desc *desc; +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,2,0) + list_for_each_entry(desc, &pdev->msi_list, list) + bf_msix_mask_irq(desc, irq_state); +#else + for_each_pci_msi_entry(desc, pdev) + bf_msix_mask_irq(desc, irq_state); +#endif + } + pci_cfg_access_unlock(pdev); + + return 0; +} + +/** + * interrupt handler which will check if the interrupt is from the right + * device. If so, disable it here and will be enabled later. + */ +static irqreturn_t bf_pci_irqhandler(int irq, struct bf_pci_dev *bfdev) +{ + /* Legacy mode need to mask in hardware */ + if (bfdev->mode == BF_INTR_MODE_LEGACY && + !pci_check_and_mask_intx(bfdev->pdev)) + return IRQ_NONE; + + /* NOTE : if bfdev->info.pci_error_state == 1, then do not access the + * device and return IRQ_NOTHANDLED. + */ + /* Message signal mode, no share IRQ and automasked */ + return IRQ_HANDLED; +} + +/* Remap pci resources described by bar #pci_bar */ +static int +bf_pci_setup_iomem(struct pci_dev *dev, struct bf_dev_info *info, + int n, int pci_bar, const char *name) +{ + unsigned long addr, len; + void *internal_addr; + + if (sizeof(info->mem) / sizeof(info->mem[0]) <= n) + return -EINVAL; + + addr = pci_resource_start(dev, pci_bar); + len = pci_resource_len(dev, pci_bar); + if (addr == 0 || len == 0) + return -1; + internal_addr = pci_ioremap_bar(dev, pci_bar); + if (internal_addr == NULL) + return -1; + info->mem[n].name = name; + info->mem[n].addr = addr; + info->mem[n].internal_addr = internal_addr; + info->mem[n].size = len; + return 0; +} + +/* Unmap previously ioremap'd resources */ +static void +bf_pci_release_iomem(struct bf_dev_info *info) +{ + int i; + + for (i = 0; i < BF_MAX_BAR_MAPS; i++) { + if (info->mem[i].internal_addr) + iounmap(info->mem[i].internal_addr); + } +} + +static int +bf_setup_bars(struct pci_dev *dev, struct bf_dev_info *info) +{ + int i, iom, ret; + unsigned long flags; + static const char *bar_names[BF_MAX_BAR_MAPS] = { + "BAR0", "BAR1", "BAR2", "BAR3", "BAR4", "BAR5", + }; + + iom = 0; + + for (i = 0; i < BF_MAX_BAR_MAPS; i++) { + if (pci_resource_len(dev, i) != 0 && + pci_resource_start(dev, i) != 0) { + flags = pci_resource_flags(dev, i); + if (flags & IORESOURCE_MEM) { + ret = bf_pci_setup_iomem(dev, info, iom, i, bar_names[i]); + if (ret != 0) + return ret; + iom++; + } + } + } + return (iom != 0) ? ret : -ENOENT; +} + +static irqreturn_t bf_interrupt(int irq, void *bfdev_id) +{ + struct bf_pci_dev *bfdev = ((struct bf_int_vector *)bfdev_id)->bf_dev; + int vect_off = ((struct bf_int_vector *)bfdev_id)->int_vec_offset; + + irqreturn_t ret = bf_pci_irqhandler(irq, bfdev); + + if (ret == IRQ_HANDLED) + atomic_inc(&(bfdev->info.event[vect_off])); + + return ret; +} + +struct bf_listener { + struct bf_pci_dev *bfdev; + s32 event_count[BF_MSIX_ENTRY_CNT]; +}; + +static unsigned int bf_poll(struct file *filep, poll_table *wait) +{ + struct bf_listener *listener = (struct bf_listener *)filep->private_data; + struct bf_pci_dev *bfdev = listener->bfdev; + int i; + + if (!bfdev->info.irq) + return -EIO; + + poll_wait(filep, &bfdev->info.wait, wait); + + for (i = 0; i < BF_MSIX_ENTRY_CNT; i++) + if (listener->event_count[i] != atomic_read(&bfdev->info.event[i])) + return POLLIN | POLLRDNORM; + return 0; +} + +static int bf_find_mem_index(struct vm_area_struct *vma) +{ + struct bf_pci_dev *bfdev = vma->vm_private_data; + if (vma->vm_pgoff < BF_MAX_BAR_MAPS) { + if (bfdev->info.mem[vma->vm_pgoff].size == 0) + return -1; + return (int)vma->vm_pgoff; + } + return -1; +} + +static const struct vm_operations_struct bf_physical_vm_ops = { +#ifdef CONFIG_HAVE_IOREMAP_PROT + .access = generic_access_phys, +#endif +}; + +static int bf_mmap_physical(struct vm_area_struct *vma) +{ + struct bf_pci_dev *bfdev = vma->vm_private_data; + int bar = bf_find_mem_index(vma); + struct bf_dev_mem *mem; + if (bar < 0) + return -EINVAL; + + mem = bfdev->info.mem + bar; + + if (mem->addr & ~PAGE_MASK) + return -ENODEV; + if (vma->vm_end - vma->vm_start > mem->size) + return -EINVAL; + + vma->vm_ops = &bf_physical_vm_ops; + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + + /* + * We cannot use the vm_iomap_memory() helper here, + * because vma->vm_pgoff is the map index we looked + * up above in bf_find_mem_index(), rather than an + * actual page offset into the mmap. + * + * So we just do the physical mmap without a page + * offset. + */ + return remap_pfn_range(vma, vma->vm_start, mem->addr >> PAGE_SHIFT, + vma->vm_end - vma->vm_start, vma->vm_page_prot); +} + +static int bf_mmap(struct file *filep, struct vm_area_struct *vma) +{ + struct bf_listener *listener = filep->private_data; + struct bf_pci_dev *bfdev = listener->bfdev; + int bar; + unsigned long requested_pages, actual_pages; + + if (vma->vm_end < vma->vm_start) + return -EINVAL; + + vma->vm_private_data = bfdev; + + bar = bf_find_mem_index(vma); + if (bar < 0) + return -EINVAL; + + requested_pages = vma_pages(vma); + actual_pages = ((bfdev->info.mem[bar].addr & ~PAGE_MASK) + + bfdev->info.mem[bar].size + PAGE_SIZE -1) >> PAGE_SHIFT; + if (requested_pages > actual_pages) + return -EINVAL; + + return bf_mmap_physical(vma); +} + +static int bf_fasync(int fd, struct file *filep, int mode) +{ + struct bf_pci_dev *bfdev = ((struct bf_listener *)filep->private_data)->bfdev; + + if (mode == 0 && &bfdev->info.async_queue == NULL) { + return 0; /* nothing to do */ + } + return (fasync_helper(fd, filep, mode, &bfdev->info.async_queue)); +} + +static int bf_open(struct inode *inode, struct file *filep) +{ + struct bf_pci_dev *bfdev; + struct bf_listener *listener; + int i; + + bfdev = container_of(inode->i_cdev, struct bf_pci_dev, cdev); + listener = kmalloc(sizeof(*listener), GFP_KERNEL); + if (listener) { + listener->bfdev = bfdev; + for (i = 0; i < BF_MSIX_ENTRY_CNT; i++) + listener->event_count[i] = atomic_read(&bfdev->info.event[i]); + filep->private_data = listener; + return 0; + } else { + return(-ENOMEM); + } +} + +static int bf_release(struct inode *inode, struct file *filep) +{ + struct bf_listener *listener = filep->private_data; + + bf_fasync(-1, filep, 0); /* empty any process id in the notification list */ + kfree(listener); + return 0; +} + +/* user space support: make read() system call after poll() of select() */ +static ssize_t bf_read(struct file *filep, char __user *buf, + size_t count, loff_t *ppos) +{ + struct bf_listener *listener = filep->private_data; + struct bf_pci_dev *bfdev = listener->bfdev; + int retval, event_count[BF_MSIX_ENTRY_CNT]; + int i, mismatch_found = 0; /* OR of per vector mismatch */ + unsigned char cnt_match[BF_MSIX_ENTRY_CNT]; /* per vector mismatch */ + + /* irq must be setup for read() to work */ + if (!bfdev->info.irq) + return -EIO; + + /* ensure that there is enough space on user buffer for the given interrupt + * mode */ + if (bfdev->mode == BF_INTR_MODE_MSIX) { + if (count < sizeof(s32)*BF_MSIX_ENTRY_CNT) + return -EINVAL; + count = sizeof(s32)*BF_MSIX_ENTRY_CNT; + } else if (bfdev->mode == BF_INTR_MODE_MSI) { + if (count < sizeof(s32)*BF_MSI_ENTRY_CNT) + return -EINVAL; + count = sizeof(s32)*BF_MSI_ENTRY_CNT; + } else { + if (count < sizeof(s32)) + return -EINVAL; + count = sizeof(s32); + } + count = sizeof(s32)*BF_MSIX_ENTRY_CNT; + + do { + set_current_state(TASK_INTERRUPTIBLE); + + for (i = 0; i < (count/sizeof(s32)); i++) { + event_count[i] = atomic_read(&(bfdev->info.event[i])); + if (event_count[i] != listener->event_count[i]) { + mismatch_found |= 1; + cnt_match[i] = 1; + } else { + event_count[i] = 0; + cnt_match[i] = 0; + } + } + if (mismatch_found) { + __set_current_state(TASK_RUNNING); + if (copy_to_user(buf, &event_count, count)) + retval = -EFAULT; + else { /* adjust the listener->event_count; */ + for (i = 0 ; i < BF_MSIX_ENTRY_CNT; i++) { + if (cnt_match[i]) { + listener->event_count[i] = event_count[i]; + } + } + retval = count; + } + break; + } + + if (filep->f_flags & O_NONBLOCK) { + retval = -EAGAIN; + break; + } + + if (signal_pending(current)) { + retval = -ERESTARTSYS; + break; + } + schedule(); + } while (1); + + __set_current_state(TASK_RUNNING); + + return retval; +} + +/* user space is supposed to call this after it is done with interrupt + * processing + */ +static ssize_t bf_write(struct file *filep, const char __user *buf, + size_t count, loff_t *ppos) +{ + struct bf_listener *listener = filep->private_data; + struct bf_pci_dev *bfdev = listener->bfdev; + ssize_t ret; + s32 int_en; + + if (!bfdev || !bfdev->info.irq) + return -EIO; + + if (count != sizeof(s32)) + return -EINVAL; + + if (copy_from_user(&int_en, buf, count)) + return -EFAULT; + + /* clear pci_error_state */ + bfdev->info.pci_error_state = 0; + + ret = bf_pci_irqcontrol(bfdev, int_en); + + return ret ? ret : sizeof(s32); +} + +static const struct file_operations bf_fops = { + .owner = THIS_MODULE, + .open = bf_open, + .release = bf_release, + .read = bf_read, + .write = bf_write, + .mmap = bf_mmap, + .poll = bf_poll, + .fasync = bf_fasync, +}; + +static int bf_major_init(struct bf_pci_dev *bfdev) +{ + static const char name[] = "bf"; + dev_t bf_dev = 0; + int result; + + result = alloc_chrdev_region(&bf_dev, 0, BF_MAX_DEVICE_CNT, name); + if (result) + return result; + + result = -ENOMEM; +/* following code useful if we chose to allocate cdev here + * + *struct cdev *cdev = NULL; + * cdev = cdev_alloc(); + * if (!cdev) + * goto fail_unregister; + * cdev->ops = &bf_fops; + * cdev->owner = THIS_MODULE; + * kobject_set_name(&cdev->kobj, "%s", name); + * result = cdev_add(cdev, bf_dev, BF_MAX_DEVICE_CNT); + */ + cdev_init(&bfdev->cdev, &bf_fops); + bfdev->cdev.owner = THIS_MODULE; + bfdev->cdev.ops = &bf_fops; + + result = cdev_add(&bfdev->cdev, bf_dev, BF_MAX_DEVICE_CNT); + if (result) + goto fail_dev_add; + + bf_major = MAJOR(bf_dev); + return 0; + +fail_dev_add: + unregister_chrdev_region(bf_dev, BF_MAX_DEVICE_CNT); + return result; +} + +static void bf_major_cleanup(struct bf_pci_dev *bfdev) +{ + unregister_chrdev_region(MKDEV(bf_major, 0), BF_MAX_DEVICE_CNT); + cdev_del(&bfdev->cdev); +} + +static int bf_init_cdev(struct bf_pci_dev *bfdev) +{ + int ret; + ret = bf_major_init(bfdev); + if (ret) + return ret; + + bf_class = class_create(THIS_MODULE, BF_CLASS_NAME); + if (!bf_class) { + printk(KERN_ERR "create_class failed for bf_dev\n"); + ret = -ENODEV; + goto err_class_register; + } + return 0; + +err_class_register: + bf_major_cleanup(bfdev); + return ret; +} + +static void bf_remove_cdev(struct bf_pci_dev *bfdev) +{ + class_destroy(bf_class); + bf_major_cleanup(bfdev); +} + + +/** + * bf_register_device - register a new userspace mem device + * @parent: parent device + * @bfdev: bf pci device + * + * returns zero on success or a negative error code. + */ +int bf_register_device(struct device *parent, struct bf_pci_dev *bfdev) +{ + struct bf_dev_info *info = &bfdev->info; + int i, j, ret = 0; + int minor; + + if (!parent || !info || !info->version) + return -EINVAL; + + init_waitqueue_head(&info->wait); + + for (i = 0; i < BF_MSIX_ENTRY_CNT; i++) { + atomic_set(&info->event[i], 0); + } + + ret = bf_init_cdev(bfdev); + if (ret) { + printk(KERN_ERR "BF: device cdev creation failed\n"); + return ret; + } + + if (bf_get_next_minor_no(&minor)) { + return -EINVAL; + } + + info->dev = device_create(bf_class, parent, + MKDEV(bf_major, minor), bfdev, + "bf%d", minor); + if (!info->dev) { + printk(KERN_ERR "BF: device creation failed\n"); + return -ENODEV; + } + + info->minor = minor; + + /* bind ISRs and request interrupts */ + if (info->irq && (bfdev->mode != BF_INTR_MODE_NONE)) { + /* + * Note that we deliberately don't use devm_request_irq + * here. The parent module can unregister the UIO device + * and call pci_disable_msi, which requires that this + * irq has been freed. However, the device may have open + * FDs at the time of unregister and therefore may not be + * freed until they are released. + */ + if (bfdev->mode == BF_INTR_MODE_LEGACY) { + ret = request_irq(info->irq, bf_interrupt, + info->irq_flags, bfdev->name, + (void *)&(bfdev->bf_int_vec[0])); + if (ret) { + printk(KERN_ERR "bf failed to request legacy irq %ld error %d\n", + info->irq, ret); + return ret; + } + printk(KERN_NOTICE "BF allocating legacy int vector %ld\n", info->irq); + } else if (bfdev->mode == BF_INTR_MODE_MSIX) { + for (i = 0; i < info->num_irq; i++) { + ret = request_irq(info->msix_entries[i].vector, bf_interrupt, + info->irq_flags, bfdev->name, + (void *)&(bfdev->bf_int_vec[i])); + if (ret) { + /* undo all other previous bindings */ + printk(KERN_ERR "bf failed to request MSIX ret %d itr %d\n", ret, i); + for (j = i - 1; j >= 0; j--) { + free_irq(info->msix_entries[j].vector, + (void *)&(bfdev->bf_int_vec[j])); + } + return ret; + } + } + printk(KERN_NOTICE "BF allocating %d MSIx vectors from %ld\n", + info->num_irq, info->irq); + } else if (bfdev->mode == BF_INTR_MODE_MSI) { + for (i = 0; i < info->num_irq; i++) { + ret = request_irq(info->irq + i, bf_interrupt, + info->irq_flags, bfdev->name, + (void *)&(bfdev->bf_int_vec[i])); + if (ret) { + /* undo all other previous bindings */ + printk(KERN_ERR "bf failed to request MSI ret %d itr %d\n", ret, i); + for (j = i - 1; j >= 0; j--) { + free_irq(info->irq + j, (void *)&(bfdev->bf_int_vec[j])); + } + return ret; + } + } + printk(KERN_NOTICE "BF allocating %d MSI vectors from %ld\n", + info->num_irq, info->irq); + } + } + return 0; +} + +/** + * bf_unregister_device - register a new userspace mem device + * @bfdev: bf pci device + * + * returns none + */ +void bf_unregister_device(struct bf_pci_dev *bfdev) +{ + struct bf_dev_info *info = &bfdev->info; + int i; + + if (info->irq) { + if (bfdev->mode == BF_INTR_MODE_LEGACY) { + free_irq(info->irq, (void *)&(bfdev->bf_int_vec[0])); + } else if (bfdev->mode == BF_INTR_MODE_MSIX) { + for (i = 0; i < info->num_irq; i++) { + free_irq(info->msix_entries[i].vector, (void *)&(bfdev->bf_int_vec[i])); + } + } else if (bfdev->mode == BF_INTR_MODE_MSI) { + for (i = 0; i < info->num_irq; i++) { + free_irq(info->irq + i, (void *)&(bfdev->bf_int_vec[i])); + } + } + } + device_destroy(bf_class, MKDEV(bf_major, info->minor)); + bf_remove_cdev(bfdev); + bf_return_minor_no(info->minor); + return; +} + +static inline struct device *pci_dev_to_dev(struct pci_dev *pdev) +{ + return &pdev->dev; +} + +static int +bf_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) +{ + struct bf_pci_dev *bfdev; + int err, pci_use_highmem; + int i, num_irq; + + bfdev = kzalloc(sizeof(struct bf_pci_dev), GFP_KERNEL); + if (!bfdev) + return -ENOMEM; + + /* init the cookies to be passed to ISRs */ + for (i = 0; i < BF_MSIX_ENTRY_CNT; i++) { + bfdev->bf_int_vec[i].int_vec_offset = i; + bfdev->bf_int_vec[i].bf_dev = bfdev; + } + + bfdev->info.async_queue = NULL; + + /* initialize intr_mode to none */ + bfdev->mode = BF_INTR_MODE_NONE; + + /* clear pci_error_state */ + bfdev->info.pci_error_state = 0; + + /* + * enable device + */ + err = pci_enable_device(pdev); + if (err != 0) { + dev_err(&pdev->dev, "Cannot enable PCI device\n"); + goto fail_free; + } + + /* + * reserve device's PCI memory regions for use by this + * module + */ + err = pci_request_regions(pdev, "bf_umem"); + if (err != 0) { + dev_err(&pdev->dev, "Cannot request regions\n"); + goto fail_pci_disable; + } + /* remap IO memory */ + err = bf_setup_bars(pdev, &bfdev->info); + if (err != 0) + goto fail_release_iomem; + + if (!dma_set_mask(pci_dev_to_dev(pdev), DMA_BIT_MASK(64)) && + !dma_set_coherent_mask(pci_dev_to_dev(pdev), DMA_BIT_MASK(64))) { + pci_use_highmem = 1; + } else { + err = dma_set_mask(pci_dev_to_dev(pdev), DMA_BIT_MASK(32)); + if (err) { + err = dma_set_coherent_mask(pci_dev_to_dev(pdev), + DMA_BIT_MASK(32)); + if (err) { + dev_err(pci_dev_to_dev(pdev), "No usable DMA " + "configuration, aborting\n"); + goto fail_release_iomem; + } + } + pci_use_highmem = 0; + } + + /* enable pci error reporting */ + /* for the current kernel version, kernel config must have set the followings: + * CONFIG_PCIEPORTBUS=y and CONFIG_PCIEAER = y + * we have pci_error_handlers defined that gets invoked by kernel AER module + * upon detecting the pcie error on this device's addresses. + * However, there seems no way that AER would pass the offending addresses + * to the callback functions. AER logs the error messages on the console. + * This driver's calback function send the SIGIO signal to the user space + * to indicate the error condition. + */ + pci_enable_pcie_error_reporting(pdev); + + /* enable bus mastering on the device */ + pci_set_master(pdev); + + /* fill in bfdev info */ + bfdev->info.version = "0.2"; + bfdev->info.owner = THIS_MODULE; + bfdev->pdev = pdev; + + switch (bf_intr_mode_default) { +#ifdef CONFIG_PCI_MSI + case BF_INTR_MODE_MSIX: + /* Only 1 msi-x vector needed */ + bfdev->info.msix_entries = kcalloc(BF_MSIX_ENTRY_CNT, + sizeof(struct msix_entry), GFP_KERNEL); + if (!bfdev->info.msix_entries) { + err = -ENOMEM; + goto fail_clear_pci_master; + } + for (i = 0; i < BF_MSIX_ENTRY_CNT; i++) { + bfdev->info.msix_entries[i].entry= i; + } + num_irq = pci_enable_msix_range(pdev, bfdev->info.msix_entries, + BF_MSIX_ENTRY_CNT, BF_MSIX_ENTRY_CNT); + if (num_irq == BF_MSIX_ENTRY_CNT) { + dev_dbg(&pdev->dev, "using MSI-X"); + bfdev->info.num_irq = num_irq; + bfdev->info.irq = bfdev->info.msix_entries[0].vector; + bfdev->mode = BF_INTR_MODE_MSIX; + printk(KERN_DEBUG "bf using %d MSIX irq from %ld\n", num_irq, + bfdev->info.irq); + break; + } else { + if (num_irq) + pci_disable_msix(pdev); + kfree(bfdev->info.msix_entries); + bfdev->info.msix_entries = NULL; + printk(KERN_ERR "bf error allocating MSIX vectors. Trying MSI...\n"); + /* and, fall back to MSI */ + } + /* ** intentional no-break */ + case BF_INTR_MODE_MSI: + num_irq = pci_enable_msi_range(pdev, BF_MSI_ENTRY_CNT, BF_MSI_ENTRY_CNT); + if (num_irq > 0) { + dev_dbg(&pdev->dev, "using MSI"); + bfdev->info.num_irq = num_irq; + bfdev->info.irq = pdev->irq; + bfdev->mode = BF_INTR_MODE_MSI; + printk(KERN_DEBUG "bf using %d MSI irq from %ld\n", bfdev->info.num_irq, + bfdev->info.irq); + break; + } +#endif /* CONFIG_PCI_MSI */ + /* fall back to Legacy Interrupt, intentional no-break */ + + case BF_INTR_MODE_LEGACY: + if (pci_intx_mask_supported(pdev)) { + dev_dbg(&pdev->dev, "using INTX"); + bfdev->info.irq_flags = IRQF_SHARED; + bfdev->info.irq = pdev->irq; + bfdev->mode = BF_INTR_MODE_LEGACY; + printk(KERN_DEBUG "bf using LEGACY irq %ld\n", bfdev->info.irq); + break; + } + dev_notice(&pdev->dev, "PCI INTx mask not supported\n"); + /* fall back to no Interrupt, intentional no-break */ + case BF_INTR_MODE_NONE: + bfdev->info.irq = 0; + bfdev->info.num_irq = 0; + bfdev->mode = BF_INTR_MODE_NONE; + break; + + default: + dev_err(&pdev->dev, "invalid IRQ mode %u", bf_intr_mode_default); + err = -EINVAL; + goto fail_clear_pci_master; + } + + /* register bf driver */ + err = bf_register_device(&pdev->dev, bfdev); + if (err != 0) + goto fail_release_irq; + sprintf(bfdev->name, "bf_%d", bfdev->info.minor); + pci_set_drvdata(pdev, bfdev); + + dev_info(&pdev->dev, "bf device %d registered with irq %ld\n", + bfdev->instance, bfdev->info.irq); + printk(KERN_ALERT "bf probe ok\n"); + return 0; + +fail_release_irq: + if (bfdev->mode == BF_INTR_MODE_MSIX) { + pci_disable_msix(bfdev->pdev); + kfree(bfdev->info.msix_entries); + bfdev->info.msix_entries = NULL; + } + else if (bfdev->mode == BF_INTR_MODE_MSI) + pci_disable_msi(bfdev->pdev); +fail_clear_pci_master: + pci_clear_master(pdev); +fail_release_iomem: + bf_pci_release_iomem(&bfdev->info); + pci_release_regions(pdev); +fail_pci_disable: + pci_disable_device(pdev); +fail_free: + kfree(bfdev); + + printk(KERN_ERR "bf probe not ok\n"); + return err; +} + +static void +bf_pci_remove(struct pci_dev *pdev) +{ + struct bf_pci_dev *bfdev = pci_get_drvdata(pdev); + + bf_unregister_device(bfdev); + if (bfdev->mode == BF_INTR_MODE_MSIX) { + pci_disable_msix(pdev); + kfree(bfdev->info.msix_entries); + bfdev->info.msix_entries = NULL; + } + else if (bfdev->mode == BF_INTR_MODE_MSI) + pci_disable_msi(pdev); + pci_clear_master(pdev); + bf_pci_release_iomem(&bfdev->info); + pci_release_regions(pdev); + pci_disable_pcie_error_reporting(pdev); + pci_disable_device(pdev); + pci_set_drvdata(pdev, NULL); + kfree(bfdev); +} + +/** + * bf_pci_error_detected - called when PCI error is detected + * @pdev: Pointer to PCI device + * @state: The current pci connection state + * + * called when root complex detects pci error associated with the device + */ +static pci_ers_result_t bf_pci_error_detected(struct pci_dev *pdev, + pci_channel_state_t state) +{ + struct bf_pci_dev *bfdev = pci_get_drvdata(pdev); + + if (!bfdev) { + return PCI_ERS_RESULT_NONE; + } + printk(KERN_ERR "pci_err_detected state %d asyncQ %p\n", state, &bfdev->info.async_queue); + if (state == pci_channel_io_perm_failure || state == pci_channel_io_frozen) { + bfdev->info.pci_error_state = 1; + /* send a signal to the user space program of the error */ + if (bfdev->info.async_queue) { + kill_fasync(&bfdev->info.async_queue, SIGIO, POLL_ERR); + } + return PCI_ERS_RESULT_DISCONNECT; + } else { + return PCI_ERS_RESULT_NONE; + } +} + +/** + * bf_pci_slot_reset - called after the pci bus has been reset. + * @pdev: Pointer to PCI device + * + * Restart the card from scratch, as if from a cold-boot. + */ +static pci_ers_result_t bf_pci_slot_reset(struct pci_dev *pdev) +{ + /* nothing to do for now as we do not expect to get backto normal after + * a pcie link reset + * TBD: fill in this function if tofino can recover after an error + */ + return PCI_ERS_RESULT_DISCONNECT; +} + +/** + * bf_pci_resume - called when kernel thinks the device is up on PCIe. + * @pdev: Pointer to PCI device + * + * This callback is called when the error recovery driver tells us that + * its OK to resume normal operation. + */ +static void bf_pci_resume(struct pci_dev *pdev) +{ + /* this function should never be called for Tofinoi */ + struct bf_pci_dev *bfdev = pci_get_drvdata(pdev); + + printk(KERN_ERR "BF io_resume invoked after pci error\n"); + if (bfdev) { + bfdev->info.pci_error_state = 0; + } +} + +static int +bf_config_intr_mode(char *intr_str) +{ + if (!intr_str) { + pr_info("Use MSIX interrupt by default\n"); + return 0; + } + + if (!strcmp(intr_str, BF_INTR_MODE_MSIX_NAME)) { + bf_intr_mode_default = BF_INTR_MODE_MSIX; + pr_info("Use MSIX interrupt\n"); + } else if (!strcmp(intr_str, BF_INTR_MODE_MSI_NAME)) { + bf_intr_mode_default = BF_INTR_MODE_MSI; + pr_info("Use MSI interrupt\n"); + } else if (!strcmp(intr_str, BF_INTR_MODE_LEGACY_NAME)) { + bf_intr_mode_default = BF_INTR_MODE_LEGACY; + pr_info("Use legacy interrupt\n"); + } else { + pr_info("Error: bad parameter - %s\n", intr_str); + return -EINVAL; + } + + return 0; +} + +static const struct pci_device_id bf_pci_tbl[] = { + {PCI_VDEVICE(BF, TOFINO_DEV_ID), 0}, + /* required last entry */ + { .device = 0 } +}; + +/* PCI bus error handlers */ +static struct pci_error_handlers bf_pci_err_handler = { + .error_detected = bf_pci_error_detected, + .slot_reset = bf_pci_slot_reset, + .resume = bf_pci_resume, +}; + +static struct pci_driver bf_pci_driver = { + .name = "bf", + .id_table = bf_pci_tbl, + .probe = bf_pci_probe, + .remove = bf_pci_remove, + .err_handler = &bf_pci_err_handler +}; + +static int __init +bfdrv_init(void) +{ + int ret; + + ret = bf_config_intr_mode(intr_mode); + if (ret < 0) + return ret; + + spin_lock_init(&bf_nonisr_lock); + return pci_register_driver(&bf_pci_driver); +} + +static void __exit +bfdrv_exit(void) +{ + pci_unregister_driver(&bf_pci_driver); +} + +module_init(bfdrv_init); +module_exit(bfdrv_exit); + +module_param(intr_mode, charp, S_IRUGO); +MODULE_PARM_DESC(intr_mode, +"bf interrupt mode (default=msi):\n" +" " BF_INTR_MODE_MSIX_NAME " Use MSIX interrupt\n" +" " BF_INTR_MODE_MSI_NAME " Use MSI interrupt\n" +" " BF_INTR_MODE_LEGACY_NAME " Use Legacy interrupt\n" +"\n"); + +MODULE_DEVICE_TABLE(pci, bf_pci_tbl); +MODULE_DESCRIPTION("Barefoot Tofino PCI device"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Barefoot Networks"); diff --git a/platform/barefoot/sonic-platform-modules-bfn/modules/bf_tun.c b/platform/barefoot/sonic-platform-modules-bfn/modules/bf_tun.c new file mode 100644 index 000000000000..a1ba7047baaa --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn/modules/bf_tun.c @@ -0,0 +1,2396 @@ +/* + * TUN - Universal TUN/TAP device driver. + * Copyright (C) 1999-2002 Maxim Krasnyansky + * + * 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. + * + * $Id: tun.c,v 1.15 2002/03/01 02:44:24 maxk Exp $ + */ + +/* + * Changes: + * + * Mike Kershaw 2005/08/14 + * Add TUNSETLINK ioctl to set the link encapsulation + * + * Mark Smith + * Use eth_random_addr() for tap MAC address. + * + * Harald Roelle 2004/04/20 + * Fixes in packet dropping, queue length setting and queue wakeup. + * Increased default tx queue length. + * Added ethtool API. + * Minor cleanups + * + * Daniel Podlejski + * Modifications for 2.3.99-pre5 kernel. + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#define DRV_NAME "bf_tun" +#define DRV_VERSION "1.6" +#define DRV_DESCRIPTION "Universal TUN/TAP device driver" +#define DRV_COPYRIGHT "(C) 1999-2004 Max Krasnyansky " + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/* Uncomment to enable debugging */ +/* #define TUN_DEBUG 1 */ + +#define TUN_MINOR1 201 + +#ifdef TUN_DEBUG +static int debug; + +#define tun_debug(level, tun, fmt, args...) \ +do { \ + if (tun->debug) \ + netdev_printk(level, tun->dev, fmt, ##args); \ +} while (0) +#define DBG1(level, fmt, args...) \ +do { \ + if (debug == 2) \ + printk(level fmt, ##args); \ +} while (0) +#else +#define tun_debug(level, tun, fmt, args...) \ +do { \ + if (0) \ + netdev_printk(level, tun->dev, fmt, ##args); \ +} while (0) +#define DBG1(level, fmt, args...) \ +do { \ + if (0) \ + printk(level fmt, ##args); \ +} while (0) +#endif + +#define GOODCOPY_LEN 128 + +#define FLT_EXACT_COUNT 8 +struct tap_filter { + unsigned int count; /* Number of addrs. Zero means disabled */ + u32 mask[2]; /* Mask of the hashed addrs */ + unsigned char addr[FLT_EXACT_COUNT][ETH_ALEN]; +}; + +/* DEFAULT_MAX_NUM_RSS_QUEUES were chosen to let the rx/tx queues allocated for + * the netdevice to be fit in one page. So we can make sure the success of + * memory allocation. TODO: increase the limit. */ +#define MAX_TAP_QUEUES DEFAULT_MAX_NUM_RSS_QUEUES +#define MAX_TAP_FLOWS 4096 + +#define TUN_FLOW_EXPIRE (3 * HZ) + +/* A tun_file connects an open character device to a tuntap netdevice. It + * also contains all socket related structures (except sock_fprog and tap_filter) + * to serve as one transmit queue for tuntap device. The sock_fprog and + * tap_filter were kept in tun_struct since they were used for filtering for the + * netdevice not for a specific queue (at least I didn't see the requirement for + * this). + * + * RCU usage: + * The tun_file and tun_struct are loosely coupled, the pointer from one to the + * other can only be read while rcu_read_lock or rtnl_lock is held. + */ +struct tun_file { + struct sock sk; + struct socket socket; + struct socket_wq wq; + struct tun_struct __rcu *tun; + struct net *net; + struct fasync_struct *fasync; + /* only used for fasnyc */ + unsigned int flags; + union { + u16 queue_index; + unsigned int ifindex; + }; + struct list_head next; + struct tun_struct *detached; +}; + +struct tun_flow_entry { + struct hlist_node hash_link; + struct rcu_head rcu; + struct tun_struct *tun; + + u32 rxhash; + u32 rps_rxhash; + int queue_index; + unsigned long updated; +}; + +#define TUN_NUM_FLOW_ENTRIES 1024 + +/* Since the socket were moved to tun_file, to preserve the behavior of persist + * device, socket filter, sndbuf and vnet header size were restore when the + * file were attached to a persist device. + */ +struct tun_struct { + struct tun_file __rcu *tfiles[MAX_TAP_QUEUES]; + unsigned int numqueues; + unsigned int flags; + kuid_t owner; + kgid_t group; + + struct net_device *dev; + netdev_features_t set_features; +#define TUN_USER_FEATURES (NETIF_F_HW_CSUM|NETIF_F_TSO_ECN|NETIF_F_TSO| \ + NETIF_F_TSO6|NETIF_F_UFO) + + int vnet_hdr_sz; + int sndbuf; + struct tap_filter txflt; + struct sock_fprog fprog; + /* protected by rtnl lock */ + bool filter_attached; +#ifdef TUN_DEBUG + int debug; +#endif + spinlock_t lock; + struct hlist_head flows[TUN_NUM_FLOW_ENTRIES]; + struct timer_list flow_gc_timer; + unsigned long ageing_time; + unsigned int numdisabled; + struct list_head disabled; + void *security; + u32 flow_count; +}; + +static inline u32 tun_hashfn(u32 rxhash) +{ + return rxhash & 0x3ff; +} + +static struct tun_flow_entry *tun_flow_find(struct hlist_head *head, u32 rxhash) +{ + struct tun_flow_entry *e; + + hlist_for_each_entry_rcu(e, head, hash_link) { + if (e->rxhash == rxhash) + return e; + } + return NULL; +} + +static struct tun_flow_entry *tun_flow_create(struct tun_struct *tun, + struct hlist_head *head, + u32 rxhash, u16 queue_index) +{ + struct tun_flow_entry *e = kmalloc(sizeof(*e), GFP_ATOMIC); + + if (e) { + tun_debug(KERN_INFO, tun, "create flow: hash %u index %u\n", + rxhash, queue_index); + e->updated = jiffies; + e->rxhash = rxhash; + e->rps_rxhash = 0; + e->queue_index = queue_index; + e->tun = tun; + hlist_add_head_rcu(&e->hash_link, head); + ++tun->flow_count; + } + return e; +} + +static void tun_flow_delete(struct tun_struct *tun, struct tun_flow_entry *e) +{ + tun_debug(KERN_INFO, tun, "delete flow: hash %u index %u\n", + e->rxhash, e->queue_index); + sock_rps_reset_flow_hash(e->rps_rxhash); + hlist_del_rcu(&e->hash_link); + kfree_rcu(e, rcu); + --tun->flow_count; +} + +static void tun_flow_flush(struct tun_struct *tun) +{ + int i; + + spin_lock_bh(&tun->lock); + for (i = 0; i < TUN_NUM_FLOW_ENTRIES; i++) { + struct tun_flow_entry *e; + struct hlist_node *n; + + hlist_for_each_entry_safe(e, n, &tun->flows[i], hash_link) + tun_flow_delete(tun, e); + } + spin_unlock_bh(&tun->lock); +} + +static void tun_flow_delete_by_queue(struct tun_struct *tun, u16 queue_index) +{ + int i; + + spin_lock_bh(&tun->lock); + for (i = 0; i < TUN_NUM_FLOW_ENTRIES; i++) { + struct tun_flow_entry *e; + struct hlist_node *n; + + hlist_for_each_entry_safe(e, n, &tun->flows[i], hash_link) { + if (e->queue_index == queue_index) + tun_flow_delete(tun, e); + } + } + spin_unlock_bh(&tun->lock); +} + +static void tun_flow_cleanup(unsigned long data) +{ + struct tun_struct *tun = (struct tun_struct *)data; + unsigned long delay = tun->ageing_time; + unsigned long next_timer = jiffies + delay; + unsigned long count = 0; + int i; + + tun_debug(KERN_INFO, tun, "tun_flow_cleanup\n"); + + spin_lock_bh(&tun->lock); + for (i = 0; i < TUN_NUM_FLOW_ENTRIES; i++) { + struct tun_flow_entry *e; + struct hlist_node *n; + + hlist_for_each_entry_safe(e, n, &tun->flows[i], hash_link) { + unsigned long this_timer; + count++; + this_timer = e->updated + delay; + if (time_before_eq(this_timer, jiffies)) + tun_flow_delete(tun, e); + else if (time_before(this_timer, next_timer)) + next_timer = this_timer; + } + } + + if (count) + mod_timer(&tun->flow_gc_timer, round_jiffies_up(next_timer)); + spin_unlock_bh(&tun->lock); +} + +static void tun_flow_update(struct tun_struct *tun, u32 rxhash, + struct tun_file *tfile) +{ + struct hlist_head *head; + struct tun_flow_entry *e; + unsigned long delay = tun->ageing_time; + u16 queue_index = tfile->queue_index; + + if (!rxhash) + return; + else + head = &tun->flows[tun_hashfn(rxhash)]; + + rcu_read_lock(); + + /* We may get a very small possibility of OOO during switching, not + * worth to optimize.*/ + if (tun->numqueues == 1 || tfile->detached) + goto unlock; + + e = tun_flow_find(head, rxhash); + if (likely(e)) { + /* TODO: keep queueing to old queue until it's empty? */ + e->queue_index = queue_index; + e->updated = jiffies; + sock_rps_record_flow_hash(e->rps_rxhash); + } else { + spin_lock_bh(&tun->lock); + if (!tun_flow_find(head, rxhash) && + tun->flow_count < MAX_TAP_FLOWS) + tun_flow_create(tun, head, rxhash, queue_index); + + if (!timer_pending(&tun->flow_gc_timer)) + mod_timer(&tun->flow_gc_timer, + round_jiffies_up(jiffies + delay)); + spin_unlock_bh(&tun->lock); + } + +unlock: + rcu_read_unlock(); +} + +/** + * Save the hash received in the stack receive path and update the + * flow_hash table accordingly. + */ +static inline void tun_flow_save_rps_rxhash(struct tun_flow_entry *e, u32 hash) +{ + if (unlikely(e->rps_rxhash != hash)) { + sock_rps_reset_flow_hash(e->rps_rxhash); + e->rps_rxhash = hash; + } +} + +/* We try to identify a flow through its rxhash first. The reason that + * we do not check rxq no. is because some cards(e.g 82599), chooses + * the rxq based on the txq where the last packet of the flow comes. As + * the userspace application move between processors, we may get a + * different rxq no. here. If we could not get rxhash, then we would + * hope the rxq no. may help here. + */ +static u16 tun_select_queue(struct net_device *dev, struct sk_buff *skb, + void *accel_priv, select_queue_fallback_t fallback) +{ + struct tun_struct *tun = netdev_priv(dev); + struct tun_flow_entry *e; + u32 txq = 0; + u32 numqueues = 0; + + rcu_read_lock(); + numqueues = ACCESS_ONCE(tun->numqueues); + + txq = skb_get_hash(skb); + if (txq) { + e = tun_flow_find(&tun->flows[tun_hashfn(txq)], txq); + if (e) { + tun_flow_save_rps_rxhash(e, txq); + txq = e->queue_index; + } else + /* use multiply and shift instead of expensive divide */ + txq = ((u64)txq * numqueues) >> 32; + } else if (likely(skb_rx_queue_recorded(skb))) { + txq = skb_get_rx_queue(skb); + while (unlikely(txq >= numqueues)) + txq -= numqueues; + } + + rcu_read_unlock(); + return txq; +} + +static inline bool tun_not_capable(struct tun_struct *tun) +{ + const struct cred *cred = current_cred(); + struct net *net = dev_net(tun->dev); + + return ((uid_valid(tun->owner) && !uid_eq(cred->euid, tun->owner)) || + (gid_valid(tun->group) && !in_egroup_p(tun->group))) && + !ns_capable(net->user_ns, CAP_NET_ADMIN); +} + +static void tun_set_real_num_queues(struct tun_struct *tun) +{ + netif_set_real_num_tx_queues(tun->dev, tun->numqueues); + netif_set_real_num_rx_queues(tun->dev, tun->numqueues); +} + +static void tun_disable_queue(struct tun_struct *tun, struct tun_file *tfile) +{ + tfile->detached = tun; + list_add_tail(&tfile->next, &tun->disabled); + ++tun->numdisabled; +} + +static struct tun_struct *tun_enable_queue(struct tun_file *tfile) +{ + struct tun_struct *tun = tfile->detached; + + tfile->detached = NULL; + list_del_init(&tfile->next); + --tun->numdisabled; + return tun; +} + +static void tun_queue_purge(struct tun_file *tfile) +{ + skb_queue_purge(&tfile->sk.sk_receive_queue); + skb_queue_purge(&tfile->sk.sk_error_queue); +} + +static void __tun_detach(struct tun_file *tfile, bool clean) +{ + struct tun_file *ntfile; + struct tun_struct *tun; + + tun = rtnl_dereference(tfile->tun); + + if (tun && !tfile->detached) { + u16 index = tfile->queue_index; + BUG_ON(index >= tun->numqueues); + + rcu_assign_pointer(tun->tfiles[index], + tun->tfiles[tun->numqueues - 1]); + ntfile = rtnl_dereference(tun->tfiles[index]); + ntfile->queue_index = index; + + --tun->numqueues; + if (clean) { + RCU_INIT_POINTER(tfile->tun, NULL); + sock_put(&tfile->sk); + } else + tun_disable_queue(tun, tfile); + + synchronize_net(); + tun_flow_delete_by_queue(tun, tun->numqueues + 1); + /* Drop read queue */ + tun_queue_purge(tfile); + tun_set_real_num_queues(tun); + } else if (tfile->detached && clean) { + tun = tun_enable_queue(tfile); + sock_put(&tfile->sk); + } + + if (clean) { + if (tun && tun->numqueues == 0 && tun->numdisabled == 0) { + netif_carrier_off(tun->dev); + + if (!(tun->flags & TUN_PERSIST) && + tun->dev->reg_state == NETREG_REGISTERED) + unregister_netdevice(tun->dev); + } + + BUG_ON(!test_bit(SOCK_EXTERNALLY_ALLOCATED, + &tfile->socket.flags)); + sk_release_kernel(&tfile->sk); + } +} + +static void tun_detach(struct tun_file *tfile, bool clean) +{ + rtnl_lock(); + __tun_detach(tfile, clean); + rtnl_unlock(); +} + +static void tun_detach_all(struct net_device *dev) +{ + struct tun_struct *tun = netdev_priv(dev); + struct tun_file *tfile, *tmp; + int i, n = tun->numqueues; + + for (i = 0; i < n; i++) { + tfile = rtnl_dereference(tun->tfiles[i]); + BUG_ON(!tfile); + tfile->socket.sk->sk_data_ready(tfile->socket.sk); + RCU_INIT_POINTER(tfile->tun, NULL); + --tun->numqueues; + } + list_for_each_entry(tfile, &tun->disabled, next) { + tfile->socket.sk->sk_data_ready(tfile->socket.sk); + RCU_INIT_POINTER(tfile->tun, NULL); + } + BUG_ON(tun->numqueues != 0); + + synchronize_net(); + for (i = 0; i < n; i++) { + tfile = rtnl_dereference(tun->tfiles[i]); + /* Drop read queue */ + tun_queue_purge(tfile); + sock_put(&tfile->sk); + } + list_for_each_entry_safe(tfile, tmp, &tun->disabled, next) { + tun_enable_queue(tfile); + tun_queue_purge(tfile); + sock_put(&tfile->sk); + } + BUG_ON(tun->numdisabled != 0); + + if (tun->flags & TUN_PERSIST) + module_put(THIS_MODULE); +} + +static int tun_attach(struct tun_struct *tun, struct file *file, bool skip_filter) +{ + struct tun_file *tfile = file->private_data; + int err; + + err = security_tun_dev_attach(tfile->socket.sk, tun->security); + if (err < 0) + goto out; + + err = -EINVAL; + if (rtnl_dereference(tfile->tun) && !tfile->detached) + goto out; + + err = -EBUSY; + if (!(tun->flags & TUN_TAP_MQ) && tun->numqueues == 1) + goto out; + + err = -E2BIG; + if (!tfile->detached && + tun->numqueues + tun->numdisabled == MAX_TAP_QUEUES) + goto out; + + err = 0; + + /* Re-attach the filter to persist device */ + if (!skip_filter && (tun->filter_attached == true)) { + err = __sk_attach_filter(&tun->fprog, tfile->socket.sk, + lockdep_rtnl_is_held()); + if (!err) + goto out; + } + tfile->queue_index = tun->numqueues; + rcu_assign_pointer(tfile->tun, tun); + rcu_assign_pointer(tun->tfiles[tun->numqueues], tfile); + tun->numqueues++; + + if (tfile->detached) + tun_enable_queue(tfile); + else + sock_hold(&tfile->sk); + + tun_set_real_num_queues(tun); + + /* device is allowed to go away first, so no need to hold extra + * refcnt. + */ + +out: + return err; +} + +static struct tun_struct *__tun_get(struct tun_file *tfile) +{ + struct tun_struct *tun; + + rcu_read_lock(); + tun = rcu_dereference(tfile->tun); + if (tun) + dev_hold(tun->dev); + rcu_read_unlock(); + + return tun; +} + +static struct tun_struct *tun_get(struct file *file) +{ + return __tun_get(file->private_data); +} + +static void tun_put(struct tun_struct *tun) +{ + dev_put(tun->dev); +} + +/* TAP filtering */ +static void addr_hash_set(u32 *mask, const u8 *addr) +{ + int n = ether_crc(ETH_ALEN, addr) >> 26; + mask[n >> 5] |= (1 << (n & 31)); +} + +static unsigned int addr_hash_test(const u32 *mask, const u8 *addr) +{ + int n = ether_crc(ETH_ALEN, addr) >> 26; + return mask[n >> 5] & (1 << (n & 31)); +} + +static int update_filter(struct tap_filter *filter, void __user *arg) +{ + struct { u8 u[ETH_ALEN]; } *addr; + struct tun_filter uf; + int err, alen, n, nexact; + + if (copy_from_user(&uf, arg, sizeof(uf))) + return -EFAULT; + + if (!uf.count) { + /* Disabled */ + filter->count = 0; + return 0; + } + + alen = ETH_ALEN * uf.count; + addr = kmalloc(alen, GFP_KERNEL); + if (!addr) + return -ENOMEM; + + if (copy_from_user(addr, arg + sizeof(uf), alen)) { + err = -EFAULT; + goto done; + } + + /* The filter is updated without holding any locks. Which is + * perfectly safe. We disable it first and in the worst + * case we'll accept a few undesired packets. */ + filter->count = 0; + wmb(); + + /* Use first set of addresses as an exact filter */ + for (n = 0; n < uf.count && n < FLT_EXACT_COUNT; n++) + memcpy(filter->addr[n], addr[n].u, ETH_ALEN); + + nexact = n; + + /* Remaining multicast addresses are hashed, + * unicast will leave the filter disabled. */ + memset(filter->mask, 0, sizeof(filter->mask)); + for (; n < uf.count; n++) { + if (!is_multicast_ether_addr(addr[n].u)) { + err = 0; /* no filter */ + goto done; + } + addr_hash_set(filter->mask, addr[n].u); + } + + /* For ALLMULTI just set the mask to all ones. + * This overrides the mask populated above. */ + if ((uf.flags & TUN_FLT_ALLMULTI)) + memset(filter->mask, ~0, sizeof(filter->mask)); + + /* Now enable the filter */ + wmb(); + filter->count = nexact; + + /* Return the number of exact filters */ + err = nexact; + +done: + kfree(addr); + return err; +} + +/* Returns: 0 - drop, !=0 - accept */ +static int run_filter(struct tap_filter *filter, const struct sk_buff *skb) +{ + /* Cannot use eth_hdr(skb) here because skb_mac_hdr() is incorrect + * at this point. */ + struct ethhdr *eh = (struct ethhdr *) skb->data; + int i; + + /* Exact match */ + for (i = 0; i < filter->count; i++) + if (ether_addr_equal(eh->h_dest, filter->addr[i])) + return 1; + + /* Inexact match (multicast only) */ + if (is_multicast_ether_addr(eh->h_dest)) + return addr_hash_test(filter->mask, eh->h_dest); + + return 0; +} + +/* + * Checks whether the packet is accepted or not. + * Returns: 0 - drop, !=0 - accept + */ +static int check_filter(struct tap_filter *filter, const struct sk_buff *skb) +{ + if (!filter->count) + return 1; + + return run_filter(filter, skb); +} + +/* Network device part of the driver */ + +static const struct ethtool_ops tun_ethtool_ops; + +/* Net device detach from fd. */ +static void tun_net_uninit(struct net_device *dev) +{ + tun_detach_all(dev); +} + +/* Net device open. */ +static int tun_net_open(struct net_device *dev) +{ + netif_tx_start_all_queues(dev); + return 0; +} + +/* Net device close. */ +static int tun_net_close(struct net_device *dev) +{ + netif_tx_stop_all_queues(dev); + return 0; +} + +/* Net device start xmit */ +static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev) +{ + struct tun_struct *tun = netdev_priv(dev); + int txq = skb->queue_mapping; + struct tun_file *tfile; + u32 numqueues = 0; + + rcu_read_lock(); + tfile = rcu_dereference(tun->tfiles[txq]); + numqueues = ACCESS_ONCE(tun->numqueues); + + /* Drop packet if interface is not attached */ + if (txq >= numqueues) + goto drop; + + if (numqueues == 1) { + /* Select queue was not called for the skbuff, so we extract the + * RPS hash and save it into the flow_table here. + */ + __u32 rxhash; + + rxhash = skb_get_hash(skb); + if (rxhash) { + struct tun_flow_entry *e; + e = tun_flow_find(&tun->flows[tun_hashfn(rxhash)], + rxhash); + if (e) + tun_flow_save_rps_rxhash(e, rxhash); + } + } + + tun_debug(KERN_INFO, tun, "tun_net_xmit %d\n", skb->len); + + BUG_ON(!tfile); + + /* Drop if the filter does not like it. + * This is a noop if the filter is disabled. + * Filter can be enabled only for the TAP devices. */ + if (!check_filter(&tun->txflt, skb)) + goto drop; + + if (tfile->socket.sk->sk_filter && + sk_filter(tfile->socket.sk, skb)) + goto drop; + + /* Limit the number of packets queued by dividing txq length with the + * number of queues. + */ + if (skb_queue_len(&tfile->socket.sk->sk_receive_queue) * numqueues + >= dev->tx_queue_len) + goto drop; + + if (unlikely(skb_orphan_frags(skb, GFP_ATOMIC))) + goto drop; + + if (skb->sk) { + sock_tx_timestamp(skb->sk, &skb_shinfo(skb)->tx_flags); + sw_tx_timestamp(skb); + } + + /* Orphan the skb - required as we might hang on to it + * for indefinite time. + */ + skb_orphan(skb); + + nf_reset(skb); + + /* Enqueue packet */ + skb_queue_tail(&tfile->socket.sk->sk_receive_queue, skb); + + /* Notify and wake up reader process */ + if (tfile->flags & TUN_FASYNC) + kill_fasync(&tfile->fasync, SIGIO, POLL_IN); + tfile->socket.sk->sk_data_ready(tfile->socket.sk); + + rcu_read_unlock(); + return NETDEV_TX_OK; + +drop: + dev->stats.tx_dropped++; + skb_tx_error(skb); + kfree_skb(skb); + rcu_read_unlock(); + return NETDEV_TX_OK; +} + +static void tun_net_mclist(struct net_device *dev) +{ + /* + * This callback is supposed to deal with mc filter in + * _rx_ path and has nothing to do with the _tx_ path. + * In rx path we always accept everything userspace gives us. + */ +} + +#define MIN_MTU 68 +#define MAX_MTU 65535 + +static int +tun_net_change_mtu(struct net_device *dev, int new_mtu) +{ + if (new_mtu < MIN_MTU || new_mtu + dev->hard_header_len > MAX_MTU) + return -EINVAL; + dev->mtu = new_mtu; + return 0; +} + +static netdev_features_t tun_net_fix_features(struct net_device *dev, + netdev_features_t features) +{ + struct tun_struct *tun = netdev_priv(dev); + + return (features & tun->set_features) | (features & ~TUN_USER_FEATURES); +} + +static int +tun_change_carrier(struct net_device *dev, bool new_carrier) { + if (new_carrier) + netif_carrier_on(dev); + else + netif_carrier_off(dev); + return 0; +} + +#ifdef CONFIG_NET_POLL_CONTROLLER +static void tun_poll_controller(struct net_device *dev) +{ + /* + * Tun only receives frames when: + * 1) the char device endpoint gets data from user space + * 2) the tun socket gets a sendmsg call from user space + * Since both of those are synchronous operations, we are guaranteed + * never to have pending data when we poll for it + * so there is nothing to do here but return. + * We need this though so netpoll recognizes us as an interface that + * supports polling, which enables bridge devices in virt setups to + * still use netconsole + */ + return; +} +#endif +static const struct net_device_ops tun_netdev_ops = { + .ndo_uninit = tun_net_uninit, + .ndo_open = tun_net_open, + .ndo_stop = tun_net_close, + .ndo_start_xmit = tun_net_xmit, + .ndo_change_mtu = tun_net_change_mtu, + .ndo_fix_features = tun_net_fix_features, + .ndo_select_queue = tun_select_queue, +#ifdef CONFIG_NET_POLL_CONTROLLER + .ndo_poll_controller = tun_poll_controller, +#endif +}; + +static const struct net_device_ops tap_netdev_ops = { + .ndo_uninit = tun_net_uninit, + .ndo_open = tun_net_open, + .ndo_stop = tun_net_close, + .ndo_start_xmit = tun_net_xmit, + .ndo_change_mtu = tun_net_change_mtu, + .ndo_fix_features = tun_net_fix_features, + .ndo_set_rx_mode = tun_net_mclist, + .ndo_set_mac_address = eth_mac_addr, + .ndo_validate_addr = eth_validate_addr, + .ndo_select_queue = tun_select_queue, +#ifdef CONFIG_NET_POLL_CONTROLLER + .ndo_poll_controller = tun_poll_controller, +#endif + .ndo_change_carrier = tun_change_carrier, +}; + +static void tun_flow_init(struct tun_struct *tun) +{ + int i; + + for (i = 0; i < TUN_NUM_FLOW_ENTRIES; i++) + INIT_HLIST_HEAD(&tun->flows[i]); + + tun->ageing_time = TUN_FLOW_EXPIRE; + setup_timer(&tun->flow_gc_timer, tun_flow_cleanup, (unsigned long)tun); + mod_timer(&tun->flow_gc_timer, + round_jiffies_up(jiffies + tun->ageing_time)); +} + +static void tun_flow_uninit(struct tun_struct *tun) +{ + del_timer_sync(&tun->flow_gc_timer); + tun_flow_flush(tun); +} + +/* Initialize net device. */ +static void tun_net_init(struct net_device *dev) +{ + struct tun_struct *tun = netdev_priv(dev); + + switch (tun->flags & TUN_TYPE_MASK) { + case TUN_TUN_DEV: + dev->netdev_ops = &tun_netdev_ops; + + /* Point-to-Point TUN Device */ + dev->hard_header_len = 0; + dev->addr_len = 0; + dev->mtu = 1500; + + /* Zero header length */ + dev->type = ARPHRD_NONE; + dev->flags = IFF_POINTOPOINT | IFF_NOARP | IFF_MULTICAST; + dev->tx_queue_len = TUN_READQ_SIZE*2; /* We prefer our own queue length */ + break; + + case TUN_TAP_DEV: + dev->netdev_ops = &tap_netdev_ops; + /* Ethernet TAP Device */ + ether_setup(dev); + dev->priv_flags &= ~IFF_TX_SKB_SHARING; + dev->priv_flags |= IFF_LIVE_ADDR_CHANGE; + + eth_hw_addr_random(dev); + + dev->tx_queue_len = TUN_READQ_SIZE*2; /* We prefer our own queue length */ + break; + } +} + +/* Character device part */ + +/* Poll */ +static unsigned int tun_chr_poll(struct file *file, poll_table *wait) +{ + struct tun_file *tfile = file->private_data; + struct tun_struct *tun = __tun_get(tfile); + struct sock *sk; + unsigned int mask = 0; + + if (!tun) + return POLLERR; + + sk = tfile->socket.sk; + + tun_debug(KERN_INFO, tun, "tun_chr_poll\n"); + + poll_wait(file, sk_sleep(sk), wait); + + if (!skb_queue_empty(&sk->sk_receive_queue)) + mask |= POLLIN | POLLRDNORM; + + if (sock_writeable(sk) || + (!test_and_set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags) && + sock_writeable(sk))) + mask |= POLLOUT | POLLWRNORM; + + if (tun->dev->reg_state != NETREG_REGISTERED) + mask = POLLERR; + + tun_put(tun); + return mask; +} + +/* prepad is the amount to reserve at front. len is length after that. + * linear is a hint as to how much to copy (usually headers). */ +static struct sk_buff *tun_alloc_skb(struct tun_file *tfile, + size_t prepad, size_t len, + size_t linear, int noblock) +{ + struct sock *sk = tfile->socket.sk; + struct sk_buff *skb; + int err; + + /* Under a page? Don't bother with paged skb. */ + if (prepad + len < PAGE_SIZE || !linear) + linear = len; + + skb = sock_alloc_send_pskb(sk, prepad + linear, len - linear, noblock, + &err, 0); + if (!skb) + return ERR_PTR(err); + + skb_reserve(skb, prepad); + skb_put(skb, linear); + skb->data_len = len - linear; + skb->len += len - linear; + + return skb; +} + +/* Get packet from user space buffer */ +static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile, + void *msg_control, const struct iovec *iv, + size_t total_len, size_t count, int noblock) +{ + struct tun_pi pi = { 0, cpu_to_be16(ETH_P_IP) }; + struct sk_buff *skb; + size_t len = total_len, align = NET_SKB_PAD, linear; + struct virtio_net_hdr gso = { 0 }; + int good_linear; + int offset = 0; + int copylen; + bool zerocopy = false; + int err; + u32 rxhash; + + if (!(tun->flags & TUN_NO_PI)) { + if (len < sizeof(pi)) + return -EINVAL; + len -= sizeof(pi); + + if (memcpy_fromiovecend((void *)&pi, iv, 0, sizeof(pi))) + return -EFAULT; + offset += sizeof(pi); + } + + if (tun->flags & TUN_VNET_HDR) { + if (len < tun->vnet_hdr_sz) + return -EINVAL; + len -= tun->vnet_hdr_sz; + + if (memcpy_fromiovecend((void *)&gso, iv, offset, sizeof(gso))) + return -EFAULT; + + if ((gso.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) && + gso.csum_start + gso.csum_offset + 2 > gso.hdr_len) + gso.hdr_len = gso.csum_start + gso.csum_offset + 2; + + if (gso.hdr_len > len) + return -EINVAL; + offset += tun->vnet_hdr_sz; + } + + if ((tun->flags & TUN_TYPE_MASK) == TUN_TAP_DEV) { + align += NET_IP_ALIGN; + if (unlikely(len < ETH_HLEN || + (gso.hdr_len && gso.hdr_len < ETH_HLEN))) + return -EINVAL; + } + + good_linear = SKB_MAX_HEAD(align); + + if (msg_control) { + /* There are 256 bytes to be copied in skb, so there is + * enough room for skb expand head in case it is used. + * The rest of the buffer is mapped from userspace. + */ + copylen = gso.hdr_len ? gso.hdr_len : GOODCOPY_LEN; + if (copylen > good_linear) + copylen = good_linear; + linear = copylen; + if (iov_pages(iv, offset + copylen, count) <= MAX_SKB_FRAGS) + zerocopy = true; + } + + if (!zerocopy) { + copylen = len; + if (gso.hdr_len > good_linear) + linear = good_linear; + else + linear = gso.hdr_len; + } + + skb = tun_alloc_skb(tfile, align, copylen, linear, noblock); + if (IS_ERR(skb)) { + if (PTR_ERR(skb) != -EAGAIN) + tun->dev->stats.rx_dropped++; + return PTR_ERR(skb); + } + + if (zerocopy) + err = zerocopy_sg_from_iovec(skb, iv, offset, count); + else { + err = skb_copy_datagram_from_iovec(skb, 0, iv, offset, len); + if (!err && msg_control) { + struct ubuf_info *uarg = msg_control; + uarg->callback(uarg, false); + } + } + + if (err) { + tun->dev->stats.rx_dropped++; + kfree_skb(skb); + return -EFAULT; + } + + if (gso.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) { + if (!skb_partial_csum_set(skb, gso.csum_start, + gso.csum_offset)) { + tun->dev->stats.rx_frame_errors++; + kfree_skb(skb); + return -EINVAL; + } + } + + switch (tun->flags & TUN_TYPE_MASK) { + case TUN_TUN_DEV: + if (tun->flags & TUN_NO_PI) { + switch (skb->data[0] & 0xf0) { + case 0x40: + pi.proto = htons(ETH_P_IP); + break; + case 0x60: + pi.proto = htons(ETH_P_IPV6); + break; + default: + tun->dev->stats.rx_dropped++; + kfree_skb(skb); + return -EINVAL; + } + } + + skb_reset_mac_header(skb); + skb->protocol = pi.proto; + skb->dev = tun->dev; + break; + case TUN_TAP_DEV: + skb->protocol = eth_type_trans(skb, tun->dev); + break; + } + + skb_reset_network_header(skb); + + if (gso.gso_type != VIRTIO_NET_HDR_GSO_NONE) { + pr_debug("GSO!\n"); + switch (gso.gso_type & ~VIRTIO_NET_HDR_GSO_ECN) { + case VIRTIO_NET_HDR_GSO_TCPV4: + skb_shinfo(skb)->gso_type = SKB_GSO_TCPV4; + break; + case VIRTIO_NET_HDR_GSO_TCPV6: + skb_shinfo(skb)->gso_type = SKB_GSO_TCPV6; + break; + case VIRTIO_NET_HDR_GSO_UDP: + skb_shinfo(skb)->gso_type = SKB_GSO_UDP; + if (skb->protocol == htons(ETH_P_IPV6)) + ipv6_proxy_select_ident(skb); + break; + default: + tun->dev->stats.rx_frame_errors++; + kfree_skb(skb); + return -EINVAL; + } + + if (gso.gso_type & VIRTIO_NET_HDR_GSO_ECN) + skb_shinfo(skb)->gso_type |= SKB_GSO_TCP_ECN; + + skb_shinfo(skb)->gso_size = gso.gso_size; + if (skb_shinfo(skb)->gso_size == 0) { + tun->dev->stats.rx_frame_errors++; + kfree_skb(skb); + return -EINVAL; + } + + /* Header must be checked, and gso_segs computed. */ + skb_shinfo(skb)->gso_type |= SKB_GSO_DODGY; + skb_shinfo(skb)->gso_segs = 0; + } + + /* copy skb_ubuf_info for callback when skb has no error */ + if (zerocopy) { + skb_shinfo(skb)->destructor_arg = msg_control; + skb_shinfo(skb)->tx_flags |= SKBTX_DEV_ZEROCOPY; + skb_shinfo(skb)->tx_flags |= SKBTX_SHARED_FRAG; + } + + skb_probe_transport_header(skb, 0); + + rxhash = skb_get_hash(skb); + netif_rx_ni(skb); + + tun->dev->stats.rx_packets++; + tun->dev->stats.rx_bytes += len; + + tun_flow_update(tun, rxhash, tfile); + return total_len; +} + +static ssize_t tun_chr_aio_write(struct kiocb *iocb, const struct iovec *iv, + unsigned long count, loff_t pos) +{ + struct file *file = iocb->ki_filp; + struct tun_struct *tun = tun_get(file); + struct tun_file *tfile = file->private_data; + ssize_t result; + + if (!tun) + return -EBADFD; + + tun_debug(KERN_INFO, tun, "tun_chr_write %ld\n", count); + + result = tun_get_user(tun, tfile, NULL, iv, iov_length(iv, count), + count, file->f_flags & O_NONBLOCK); + + tun_put(tun); + return result; +} + +/* Put packet to the user space buffer */ +static ssize_t tun_put_user(struct tun_struct *tun, + struct tun_file *tfile, + struct sk_buff *skb, + const struct iovec *iv, int len) +{ + struct tun_pi pi = { 0, skb->protocol }; + ssize_t total = 0; + int vlan_offset = 0, copied; + int vlan_hlen = 0; + + if (vlan_tx_tag_present(skb)) + vlan_hlen = VLAN_HLEN; + + if (!(tun->flags & TUN_NO_PI)) { + if ((len -= sizeof(pi)) < 0) + return -EINVAL; + + if (len < skb->len) { + /* Packet will be striped */ + pi.flags |= TUN_PKT_STRIP; + } + + if (memcpy_toiovecend(iv, (void *) &pi, 0, sizeof(pi))) + return -EFAULT; + total += sizeof(pi); + } + + if (tun->flags & TUN_VNET_HDR) { + struct virtio_net_hdr gso = { 0 }; /* no info leak */ + if ((len -= tun->vnet_hdr_sz) < 0) + return -EINVAL; + + if (skb_is_gso(skb)) { + struct skb_shared_info *sinfo = skb_shinfo(skb); + + /* This is a hint as to how much should be linear. */ + gso.hdr_len = skb_headlen(skb); + gso.gso_size = sinfo->gso_size; + if (sinfo->gso_type & SKB_GSO_TCPV4) + gso.gso_type = VIRTIO_NET_HDR_GSO_TCPV4; + else if (sinfo->gso_type & SKB_GSO_TCPV6) + gso.gso_type = VIRTIO_NET_HDR_GSO_TCPV6; + else if (sinfo->gso_type & SKB_GSO_UDP) + gso.gso_type = VIRTIO_NET_HDR_GSO_UDP; + else { + pr_err("unexpected GSO type: " + "0x%x, gso_size %d, hdr_len %d\n", + sinfo->gso_type, gso.gso_size, + gso.hdr_len); + print_hex_dump(KERN_ERR, "tun: ", + DUMP_PREFIX_NONE, + 16, 1, skb->head, + min((int)gso.hdr_len, 64), true); + WARN_ON_ONCE(1); + return -EINVAL; + } + if (sinfo->gso_type & SKB_GSO_TCP_ECN) + gso.gso_type |= VIRTIO_NET_HDR_GSO_ECN; + } else + gso.gso_type = VIRTIO_NET_HDR_GSO_NONE; + + if (skb->ip_summed == CHECKSUM_PARTIAL) { + gso.flags = VIRTIO_NET_HDR_F_NEEDS_CSUM; + gso.csum_start = skb_checksum_start_offset(skb) + + vlan_hlen; + gso.csum_offset = skb->csum_offset; + } else if (skb->ip_summed == CHECKSUM_UNNECESSARY) { + gso.flags = VIRTIO_NET_HDR_F_DATA_VALID; + } /* else everything is zero */ + + if (unlikely(memcpy_toiovecend(iv, (void *)&gso, total, + sizeof(gso)))) + return -EFAULT; + total += tun->vnet_hdr_sz; + } + + copied = total; + len = min_t(int, skb->len + vlan_hlen, len); + total += skb->len + vlan_hlen; + if (vlan_hlen) { + int copy, ret; + struct { + __be16 h_vlan_proto; + __be16 h_vlan_TCI; + } veth; + + veth.h_vlan_proto = skb->vlan_proto; + veth.h_vlan_TCI = htons(vlan_tx_tag_get(skb)); + + vlan_offset = offsetof(struct vlan_ethhdr, h_vlan_proto); + + copy = min_t(int, vlan_offset, len); + ret = skb_copy_datagram_const_iovec(skb, 0, iv, copied, copy); + len -= copy; + copied += copy; + if (ret || !len) + goto done; + + copy = min_t(int, sizeof(veth), len); + ret = memcpy_toiovecend(iv, (void *)&veth, copied, copy); + len -= copy; + copied += copy; + if (ret || !len) + goto done; + } + + skb_copy_datagram_const_iovec(skb, vlan_offset, iv, copied, len); + +done: + tun->dev->stats.tx_packets++; + tun->dev->stats.tx_bytes += len; + + return total; +} + +static ssize_t tun_do_read(struct tun_struct *tun, struct tun_file *tfile, + const struct iovec *iv, ssize_t len, int noblock) +{ + struct sk_buff *skb; + ssize_t ret = 0; + int peeked, err, off = 0; + + tun_debug(KERN_INFO, tun, "tun_do_read\n"); + + if (!len) + return ret; + + if (tun->dev->reg_state != NETREG_REGISTERED) + return -EIO; + + /* Read frames from queue */ + skb = __skb_recv_datagram(tfile->socket.sk, noblock ? MSG_DONTWAIT : 0, + &peeked, &off, &err); + if (skb) { + ret = tun_put_user(tun, tfile, skb, iv, len); + kfree_skb(skb); + } else + ret = err; + + return ret; +} + +static ssize_t tun_chr_aio_read(struct kiocb *iocb, const struct iovec *iv, + unsigned long count, loff_t pos) +{ + struct file *file = iocb->ki_filp; + struct tun_file *tfile = file->private_data; + struct tun_struct *tun = __tun_get(tfile); + ssize_t len, ret; + + if (!tun) + return -EBADFD; + len = iov_length(iv, count); + if (len < 0) { + ret = -EINVAL; + goto out; + } + + ret = tun_do_read(tun, tfile, iv, len, + file->f_flags & O_NONBLOCK); + ret = min_t(ssize_t, ret, len); + if (ret > 0) + iocb->ki_pos = ret; +out: + tun_put(tun); + return ret; +} + +static void tun_free_netdev(struct net_device *dev) +{ + struct tun_struct *tun = netdev_priv(dev); + + BUG_ON(!(list_empty(&tun->disabled))); + tun_flow_uninit(tun); + security_tun_dev_free_security(tun->security); + free_netdev(dev); +} + +static void tun_setup(struct net_device *dev) +{ + struct tun_struct *tun = netdev_priv(dev); + + tun->owner = INVALID_UID; + tun->group = INVALID_GID; + + dev->ethtool_ops = &tun_ethtool_ops; + dev->destructor = tun_free_netdev; +} + +/* Trivial set of netlink ops to allow deleting tun or tap + * device with netlink. + */ +static int tun_validate(struct nlattr *tb[], struct nlattr *data[]) +{ + return -EINVAL; +} + +static struct rtnl_link_ops tun_link_ops __read_mostly = { + .kind = DRV_NAME, + .priv_size = sizeof(struct tun_struct), + .setup = tun_setup, + .validate = tun_validate, +}; + +static void tun_sock_write_space(struct sock *sk) +{ + struct tun_file *tfile; + wait_queue_head_t *wqueue; + + if (!sock_writeable(sk)) + return; + + if (!test_and_clear_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags)) + return; + + wqueue = sk_sleep(sk); + if (wqueue && waitqueue_active(wqueue)) + wake_up_interruptible_sync_poll(wqueue, POLLOUT | + POLLWRNORM | POLLWRBAND); + + tfile = container_of(sk, struct tun_file, sk); + kill_fasync(&tfile->fasync, SIGIO, POLL_OUT); +} + +static int tun_sendmsg(struct kiocb *iocb, struct socket *sock, + struct msghdr *m, size_t total_len) +{ + int ret; + struct tun_file *tfile = container_of(sock, struct tun_file, socket); + struct tun_struct *tun = __tun_get(tfile); + + if (!tun) + return -EBADFD; + ret = tun_get_user(tun, tfile, m->msg_control, m->msg_iov, total_len, + m->msg_iovlen, m->msg_flags & MSG_DONTWAIT); + tun_put(tun); + return ret; +} + +static int tun_recvmsg(struct kiocb *iocb, struct socket *sock, + struct msghdr *m, size_t total_len, + int flags) +{ + struct tun_file *tfile = container_of(sock, struct tun_file, socket); + struct tun_struct *tun = __tun_get(tfile); + int ret; + + if (!tun) + return -EBADFD; + + if (flags & ~(MSG_DONTWAIT|MSG_TRUNC|MSG_ERRQUEUE)) { + ret = -EINVAL; + goto out; + } + if (flags & MSG_ERRQUEUE) { + ret = sock_recv_errqueue(sock->sk, m, total_len, + SOL_PACKET, TUN_TX_TIMESTAMP); + goto out; + } + ret = tun_do_read(tun, tfile, m->msg_iov, total_len, + flags & MSG_DONTWAIT); + if (ret > total_len) { + m->msg_flags |= MSG_TRUNC; + ret = flags & MSG_TRUNC ? ret : total_len; + } +out: + tun_put(tun); + return ret; +} + +static int tun_release(struct socket *sock) +{ + if (sock->sk) + sock_put(sock->sk); + return 0; +} + +/* Ops structure to mimic raw sockets with tun */ +static const struct proto_ops tun_socket_ops = { + .sendmsg = tun_sendmsg, + .recvmsg = tun_recvmsg, + .release = tun_release, +}; + +static struct proto tun_proto = { + .name = "bf_tun", + .owner = THIS_MODULE, + .obj_size = sizeof(struct tun_file), +}; + +static int tun_flags(struct tun_struct *tun) +{ + int flags = 0; + + if (tun->flags & TUN_TUN_DEV) + flags |= IFF_TUN; + else + flags |= IFF_TAP; + + if (tun->flags & TUN_NO_PI) + flags |= IFF_NO_PI; + + /* This flag has no real effect. We track the value for backwards + * compatibility. + */ + if (tun->flags & TUN_ONE_QUEUE) + flags |= IFF_ONE_QUEUE; + + if (tun->flags & TUN_VNET_HDR) + flags |= IFF_VNET_HDR; + + if (tun->flags & TUN_TAP_MQ) + flags |= IFF_MULTI_QUEUE; + + if (tun->flags & TUN_PERSIST) + flags |= IFF_PERSIST; + + return flags; +} + +static ssize_t tun_show_flags(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct tun_struct *tun = netdev_priv(to_net_dev(dev)); + return sprintf(buf, "0x%x\n", tun_flags(tun)); +} + +static ssize_t tun_show_owner(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct tun_struct *tun = netdev_priv(to_net_dev(dev)); + return uid_valid(tun->owner)? + sprintf(buf, "%u\n", + from_kuid_munged(current_user_ns(), tun->owner)): + sprintf(buf, "-1\n"); +} + +static ssize_t tun_show_group(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct tun_struct *tun = netdev_priv(to_net_dev(dev)); + return gid_valid(tun->group) ? + sprintf(buf, "%u\n", + from_kgid_munged(current_user_ns(), tun->group)): + sprintf(buf, "-1\n"); +} + +static DEVICE_ATTR(tun_flags, 0444, tun_show_flags, NULL); +static DEVICE_ATTR(owner, 0444, tun_show_owner, NULL); +static DEVICE_ATTR(group, 0444, tun_show_group, NULL); + +static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) +{ + struct tun_struct *tun; + struct tun_file *tfile = file->private_data; + struct net_device *dev; + int err; + + if (tfile->detached) + return -EINVAL; + + dev = __dev_get_by_name(net, ifr->ifr_name); + if (dev) { + if (ifr->ifr_flags & IFF_TUN_EXCL) + return -EBUSY; + if ((ifr->ifr_flags & IFF_TUN) && dev->netdev_ops == &tun_netdev_ops) + tun = netdev_priv(dev); + else if ((ifr->ifr_flags & IFF_TAP) && dev->netdev_ops == &tap_netdev_ops) + tun = netdev_priv(dev); + else + return -EINVAL; + + if (!!(ifr->ifr_flags & IFF_MULTI_QUEUE) != + !!(tun->flags & TUN_TAP_MQ)) + return -EINVAL; + + if (tun_not_capable(tun)) + return -EPERM; + err = security_tun_dev_open(tun->security); + if (err < 0) + return err; + + err = tun_attach(tun, file, ifr->ifr_flags & IFF_NOFILTER); + if (err < 0) + return err; + + if (tun->flags & TUN_TAP_MQ && + (tun->numqueues + tun->numdisabled > 1)) { + /* One or more queue has already been attached, no need + * to initialize the device again. + */ + return 0; + } + } + else { + char *name; + unsigned long flags = 0; + int queues = ifr->ifr_flags & IFF_MULTI_QUEUE ? + MAX_TAP_QUEUES : 1; + + if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) + return -EPERM; + err = security_tun_dev_create(); + if (err < 0) + return err; + + /* Set dev type */ + if (ifr->ifr_flags & IFF_TUN) { + /* TUN device */ + flags |= TUN_TUN_DEV; + name = "tun%d"; + } else if (ifr->ifr_flags & IFF_TAP) { + /* TAP device */ + flags |= TUN_TAP_DEV; + name = "tap%d"; + } else + return -EINVAL; + + if (*ifr->ifr_name) + name = ifr->ifr_name; + + dev = alloc_netdev_mqs(sizeof(struct tun_struct), name, + tun_setup, queues, queues); + + if (!dev) + return -ENOMEM; + + dev_net_set(dev, net); + dev->rtnl_link_ops = &tun_link_ops; + dev->ifindex = tfile->ifindex; + + tun = netdev_priv(dev); + tun->dev = dev; + tun->flags = flags; + tun->txflt.count = 0; + tun->vnet_hdr_sz = sizeof(struct virtio_net_hdr); + + tun->filter_attached = false; + tun->sndbuf = tfile->socket.sk->sk_sndbuf; + + spin_lock_init(&tun->lock); + + err = security_tun_dev_alloc_security(&tun->security); + if (err < 0) + goto err_free_dev; + + tun_net_init(dev); + tun_flow_init(tun); + + dev->hw_features = NETIF_F_SG | NETIF_F_FRAGLIST | + TUN_USER_FEATURES | NETIF_F_HW_VLAN_CTAG_TX | + NETIF_F_HW_VLAN_STAG_TX; + dev->features = dev->hw_features; + dev->vlan_features = dev->features & + ~(NETIF_F_HW_VLAN_CTAG_TX | + NETIF_F_HW_VLAN_STAG_TX); + + INIT_LIST_HEAD(&tun->disabled); + err = tun_attach(tun, file, false); + if (err < 0) + goto err_free_flow; + + err = register_netdevice(tun->dev); + if (err < 0) + goto err_detach; + + if (device_create_file(&tun->dev->dev, &dev_attr_tun_flags) || + device_create_file(&tun->dev->dev, &dev_attr_owner) || + device_create_file(&tun->dev->dev, &dev_attr_group)) + pr_err("Failed to create tun sysfs files\n"); + } + + netif_carrier_on(tun->dev); + + tun_debug(KERN_INFO, tun, "tun_set_iff\n"); + + if (ifr->ifr_flags & IFF_NO_PI) + tun->flags |= TUN_NO_PI; + else + tun->flags &= ~TUN_NO_PI; + + /* This flag has no real effect. We track the value for backwards + * compatibility. + */ + if (ifr->ifr_flags & IFF_ONE_QUEUE) + tun->flags |= TUN_ONE_QUEUE; + else + tun->flags &= ~TUN_ONE_QUEUE; + + if (ifr->ifr_flags & IFF_VNET_HDR) + tun->flags |= TUN_VNET_HDR; + else + tun->flags &= ~TUN_VNET_HDR; + + if (ifr->ifr_flags & IFF_MULTI_QUEUE) + tun->flags |= TUN_TAP_MQ; + else + tun->flags &= ~TUN_TAP_MQ; + + /* Make sure persistent devices do not get stuck in + * xoff state. + */ + if (netif_running(tun->dev)) + netif_tx_wake_all_queues(tun->dev); + + strcpy(ifr->ifr_name, tun->dev->name); + return 0; + +err_detach: + tun_detach_all(dev); +err_free_flow: + tun_flow_uninit(tun); + security_tun_dev_free_security(tun->security); +err_free_dev: + free_netdev(dev); + return err; +} + +static void tun_get_iff(struct net *net, struct tun_struct *tun, + struct ifreq *ifr) +{ + tun_debug(KERN_INFO, tun, "tun_get_iff\n"); + + strcpy(ifr->ifr_name, tun->dev->name); + + ifr->ifr_flags = tun_flags(tun); + +} + +/* This is like a cut-down ethtool ops, except done via tun fd so no + * privs required. */ +static int set_offload(struct tun_struct *tun, unsigned long arg) +{ + netdev_features_t features = 0; + + if (arg & TUN_F_CSUM) { + features |= NETIF_F_HW_CSUM; + arg &= ~TUN_F_CSUM; + + if (arg & (TUN_F_TSO4|TUN_F_TSO6)) { + if (arg & TUN_F_TSO_ECN) { + features |= NETIF_F_TSO_ECN; + arg &= ~TUN_F_TSO_ECN; + } + if (arg & TUN_F_TSO4) + features |= NETIF_F_TSO; + if (arg & TUN_F_TSO6) + features |= NETIF_F_TSO6; + arg &= ~(TUN_F_TSO4|TUN_F_TSO6); + } + + if (arg & TUN_F_UFO) { + features |= NETIF_F_UFO; + arg &= ~TUN_F_UFO; + } + } + + /* This gives the user a way to test for new features in future by + * trying to set them. */ + if (arg) + return -EINVAL; + + tun->set_features = features; + netdev_update_features(tun->dev); + + return 0; +} + +static void tun_detach_filter(struct tun_struct *tun, int n) +{ + int i; + struct tun_file *tfile; + + for (i = 0; i < n; i++) { + tfile = rtnl_dereference(tun->tfiles[i]); + __sk_detach_filter(tfile->socket.sk, lockdep_rtnl_is_held()); + } + + tun->filter_attached = false; +} + +static int tun_attach_filter(struct tun_struct *tun) +{ + int i, ret = 0; + struct tun_file *tfile; + + for (i = 0; i < tun->numqueues; i++) { + tfile = rtnl_dereference(tun->tfiles[i]); + ret = __sk_attach_filter(&tun->fprog, tfile->socket.sk, + lockdep_rtnl_is_held()); + if (ret) { + tun_detach_filter(tun, i); + return ret; + } + } + + tun->filter_attached = true; + return ret; +} + +static void tun_set_sndbuf(struct tun_struct *tun) +{ + struct tun_file *tfile; + int i; + + for (i = 0; i < tun->numqueues; i++) { + tfile = rtnl_dereference(tun->tfiles[i]); + tfile->socket.sk->sk_sndbuf = tun->sndbuf; + } +} + +static int tun_set_queue(struct file *file, struct ifreq *ifr) +{ + struct tun_file *tfile = file->private_data; + struct tun_struct *tun; + int ret = 0; + + rtnl_lock(); + + if (ifr->ifr_flags & IFF_ATTACH_QUEUE) { + tun = tfile->detached; + if (!tun) { + ret = -EINVAL; + goto unlock; + } + ret = security_tun_dev_attach_queue(tun->security); + if (ret < 0) + goto unlock; + ret = tun_attach(tun, file, false); + } else if (ifr->ifr_flags & IFF_DETACH_QUEUE) { + tun = rtnl_dereference(tfile->tun); + if (!tun || !(tun->flags & TUN_TAP_MQ) || tfile->detached) + ret = -EINVAL; + else + __tun_detach(tfile, false); + } else + ret = -EINVAL; + +unlock: + rtnl_unlock(); + return ret; +} + +static long __tun_chr_ioctl(struct file *file, unsigned int cmd, + unsigned long arg, int ifreq_len) +{ + struct tun_file *tfile = file->private_data; + struct tun_struct *tun; + void __user* argp = (void __user*)arg; + struct ifreq ifr; + kuid_t owner; + kgid_t group; + int sndbuf; + int vnet_hdr_sz; + unsigned int ifindex; + int ret; + + if (cmd == TUNSETIFF || cmd == TUNSETQUEUE || _IOC_TYPE(cmd) == 0x89) { + if (copy_from_user(&ifr, argp, ifreq_len)) + return -EFAULT; + } else { + memset(&ifr, 0, sizeof(ifr)); + } + if (cmd == TUNGETFEATURES) { + /* Currently this just means: "what IFF flags are valid?". + * This is needed because we never checked for invalid flags on + * TUNSETIFF. */ + return put_user(IFF_TUN | IFF_TAP | IFF_NO_PI | IFF_ONE_QUEUE | + IFF_VNET_HDR | IFF_MULTI_QUEUE, + (unsigned int __user*)argp); + } else if (cmd == TUNSETQUEUE) + return tun_set_queue(file, &ifr); + + ret = 0; + rtnl_lock(); + + tun = __tun_get(tfile); + if (cmd == TUNSETIFF && !tun) { + ifr.ifr_name[IFNAMSIZ-1] = '\0'; + + ret = tun_set_iff(tfile->net, file, &ifr); + + if (ret) + goto unlock; + + if (copy_to_user(argp, &ifr, ifreq_len)) + ret = -EFAULT; + goto unlock; + } + if (cmd == TUNSETIFINDEX) { + ret = -EPERM; + if (tun) + goto unlock; + + ret = -EFAULT; + if (copy_from_user(&ifindex, argp, sizeof(ifindex))) + goto unlock; + + ret = 0; + tfile->ifindex = ifindex; + goto unlock; + } + + ret = -EBADFD; + if (!tun) + goto unlock; + + tun_debug(KERN_INFO, tun, "tun_chr_ioctl cmd %u\n", cmd); + + ret = 0; + switch (cmd) { + case TUNGETIFF: + tun_get_iff(current->nsproxy->net_ns, tun, &ifr); + + if (tfile->detached) + ifr.ifr_flags |= IFF_DETACH_QUEUE; + if (!tfile->socket.sk->sk_filter) + ifr.ifr_flags |= IFF_NOFILTER; + + if (copy_to_user(argp, &ifr, ifreq_len)) + ret = -EFAULT; + break; + + case TUNSETNOCSUM: + /* Disable/Enable checksum */ + + /* [unimplemented] */ + tun_debug(KERN_INFO, tun, "ignored: set checksum %s\n", + arg ? "disabled" : "enabled"); + break; + + case TUNSETPERSIST: + /* Disable/Enable persist mode. Keep an extra reference to the + * module to prevent the module being unprobed. + */ + if (arg && !(tun->flags & TUN_PERSIST)) { + tun->flags |= TUN_PERSIST; + __module_get(THIS_MODULE); + } + if (!arg && (tun->flags & TUN_PERSIST)) { + tun->flags &= ~TUN_PERSIST; + module_put(THIS_MODULE); + } + + tun_debug(KERN_INFO, tun, "persist %s\n", + arg ? "enabled" : "disabled"); + break; + + case TUNSETOWNER: + /* Set owner of the device */ + owner = make_kuid(current_user_ns(), arg); + if (!uid_valid(owner)) { + ret = -EINVAL; + break; + } + tun->owner = owner; + tun_debug(KERN_INFO, tun, "owner set to %u\n", + from_kuid(&init_user_ns, tun->owner)); + break; + + case TUNSETGROUP: + /* Set group of the device */ + group = make_kgid(current_user_ns(), arg); + if (!gid_valid(group)) { + ret = -EINVAL; + break; + } + tun->group = group; + tun_debug(KERN_INFO, tun, "group set to %u\n", + from_kgid(&init_user_ns, tun->group)); + break; + + case TUNSETLINK: + /* Only allow setting the type when the interface is down */ + if (tun->dev->flags & IFF_UP) { + tun_debug(KERN_INFO, tun, + "Linktype set failed because interface is up\n"); + ret = -EBUSY; + } else { + tun->dev->type = (int) arg; + tun_debug(KERN_INFO, tun, "linktype set to %d\n", + tun->dev->type); + ret = 0; + } + break; + +#ifdef TUN_DEBUG + case TUNSETDEBUG: + tun->debug = arg; + break; +#endif + case TUNSETOFFLOAD: + ret = set_offload(tun, arg); + break; + + case TUNSETTXFILTER: + /* Can be set only for TAPs */ + ret = -EINVAL; + if ((tun->flags & TUN_TYPE_MASK) != TUN_TAP_DEV) + break; + ret = update_filter(&tun->txflt, (void __user *)arg); + break; + + case SIOCGIFHWADDR: + /* Get hw address */ + memcpy(ifr.ifr_hwaddr.sa_data, tun->dev->dev_addr, ETH_ALEN); + ifr.ifr_hwaddr.sa_family = tun->dev->type; + if (copy_to_user(argp, &ifr, ifreq_len)) + ret = -EFAULT; + break; + + case SIOCSIFHWADDR: + /* Set hw address */ + tun_debug(KERN_DEBUG, tun, "set hw address: %pM\n", + ifr.ifr_hwaddr.sa_data); + + ret = dev_set_mac_address(tun->dev, &ifr.ifr_hwaddr); + break; + + case TUNGETSNDBUF: + sndbuf = tfile->socket.sk->sk_sndbuf; + if (copy_to_user(argp, &sndbuf, sizeof(sndbuf))) + ret = -EFAULT; + break; + + case TUNSETSNDBUF: + if (copy_from_user(&sndbuf, argp, sizeof(sndbuf))) { + ret = -EFAULT; + break; + } + + tun->sndbuf = sndbuf; + tun_set_sndbuf(tun); + break; + + case TUNGETVNETHDRSZ: + vnet_hdr_sz = tun->vnet_hdr_sz; + if (copy_to_user(argp, &vnet_hdr_sz, sizeof(vnet_hdr_sz))) + ret = -EFAULT; + break; + + case TUNSETVNETHDRSZ: + if (copy_from_user(&vnet_hdr_sz, argp, sizeof(vnet_hdr_sz))) { + ret = -EFAULT; + break; + } + if (vnet_hdr_sz < (int)sizeof(struct virtio_net_hdr)) { + ret = -EINVAL; + break; + } + + tun->vnet_hdr_sz = vnet_hdr_sz; + break; + + case TUNATTACHFILTER: + /* Can be set only for TAPs */ + ret = -EINVAL; + if ((tun->flags & TUN_TYPE_MASK) != TUN_TAP_DEV) + break; + ret = -EFAULT; + if (copy_from_user(&tun->fprog, argp, sizeof(tun->fprog))) + break; + + ret = tun_attach_filter(tun); + break; + + case TUNDETACHFILTER: + /* Can be set only for TAPs */ + ret = -EINVAL; + if ((tun->flags & TUN_TYPE_MASK) != TUN_TAP_DEV) + break; + ret = 0; + tun_detach_filter(tun, tun->numqueues); + break; + + case TUNGETFILTER: + ret = -EINVAL; + if ((tun->flags & TUN_TYPE_MASK) != TUN_TAP_DEV) + break; + ret = -EFAULT; + if (copy_to_user(argp, &tun->fprog, sizeof(tun->fprog))) + break; + ret = 0; + break; + + default: + ret = -EINVAL; + break; + } + +unlock: + rtnl_unlock(); + if (tun) + tun_put(tun); + return ret; +} + +static long tun_chr_ioctl(struct file *file, + unsigned int cmd, unsigned long arg) +{ + return __tun_chr_ioctl(file, cmd, arg, sizeof (struct ifreq)); +} + +#ifdef CONFIG_COMPAT +static long tun_chr_compat_ioctl(struct file *file, + unsigned int cmd, unsigned long arg) +{ + switch (cmd) { + case TUNSETIFF: + case TUNGETIFF: + case TUNSETTXFILTER: + case TUNGETSNDBUF: + case TUNSETSNDBUF: + case SIOCGIFHWADDR: + case SIOCSIFHWADDR: + arg = (unsigned long)compat_ptr(arg); + break; + default: + arg = (compat_ulong_t)arg; + break; + } + + /* + * compat_ifreq is shorter than ifreq, so we must not access beyond + * the end of that structure. All fields that are used in this + * driver are compatible though, we don't need to convert the + * contents. + */ + return __tun_chr_ioctl(file, cmd, arg, sizeof(struct compat_ifreq)); +} +#endif /* CONFIG_COMPAT */ + +static int tun_chr_fasync(int fd, struct file *file, int on) +{ + struct tun_file *tfile = file->private_data; + int ret; + + if ((ret = fasync_helper(fd, file, on, &tfile->fasync)) < 0) + goto out; + + if (on) { + ret = __f_setown(file, task_pid(current), PIDTYPE_PID, 0); + if (ret) + goto out; + tfile->flags |= TUN_FASYNC; + } else + tfile->flags &= ~TUN_FASYNC; + ret = 0; +out: + return ret; +} + +static int tun_chr_open(struct inode *inode, struct file * file) +{ + struct tun_file *tfile; + + DBG1(KERN_INFO, "tunX: tun_chr_open\n"); + + tfile = (struct tun_file *)sk_alloc(&init_net, AF_UNSPEC, GFP_KERNEL, + &tun_proto); + if (!tfile) + return -ENOMEM; + RCU_INIT_POINTER(tfile->tun, NULL); + tfile->net = get_net(current->nsproxy->net_ns); + tfile->flags = 0; + tfile->ifindex = 0; + + init_waitqueue_head(&tfile->wq.wait); + RCU_INIT_POINTER(tfile->socket.wq, &tfile->wq); + + tfile->socket.file = file; + tfile->socket.ops = &tun_socket_ops; + + sock_init_data(&tfile->socket, &tfile->sk); + sk_change_net(&tfile->sk, tfile->net); + + tfile->sk.sk_write_space = tun_sock_write_space; + tfile->sk.sk_sndbuf = INT_MAX; + + file->private_data = tfile; + set_bit(SOCK_EXTERNALLY_ALLOCATED, &tfile->socket.flags); + INIT_LIST_HEAD(&tfile->next); + + sock_set_flag(&tfile->sk, SOCK_ZEROCOPY); + + return 0; +} + +static int tun_chr_close(struct inode *inode, struct file *file) +{ + struct tun_file *tfile = file->private_data; + struct net *net = tfile->net; + + tun_detach(tfile, true); + put_net(net); + + return 0; +} + +#ifdef CONFIG_PROC_FS +static int tun_chr_show_fdinfo(struct seq_file *m, struct file *f) +{ + struct tun_struct *tun; + struct ifreq ifr; + + memset(&ifr, 0, sizeof(ifr)); + + rtnl_lock(); + tun = tun_get(f); + if (tun) + tun_get_iff(current->nsproxy->net_ns, tun, &ifr); + rtnl_unlock(); + + if (tun) + tun_put(tun); + + return seq_printf(m, "iff:\t%s\n", ifr.ifr_name); +} +#endif + +static const struct file_operations tun_fops = { + .owner = THIS_MODULE, + .llseek = no_llseek, + .read = do_sync_read, + .aio_read = tun_chr_aio_read, + .write = do_sync_write, + .aio_write = tun_chr_aio_write, + .poll = tun_chr_poll, + .unlocked_ioctl = tun_chr_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = tun_chr_compat_ioctl, +#endif + .open = tun_chr_open, + .release = tun_chr_close, + .fasync = tun_chr_fasync, +#ifdef CONFIG_PROC_FS + .show_fdinfo = tun_chr_show_fdinfo, +#endif +}; + +static struct miscdevice tun_miscdev = { + .minor = (TUN_MINOR1), + .name = "bf_tun", + .nodename = "net/bf_tun", + .fops = &tun_fops, +}; + +/* ethtool interface */ + +static int tun_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + cmd->supported = 0; + cmd->advertising = 0; + ethtool_cmd_speed_set(cmd, SPEED_10); + cmd->duplex = DUPLEX_FULL; + cmd->port = PORT_TP; + cmd->phy_address = 0; + cmd->transceiver = XCVR_INTERNAL; + cmd->autoneg = AUTONEG_DISABLE; + cmd->maxtxpkt = 0; + cmd->maxrxpkt = 0; + return 0; +} + +static void tun_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) +{ + struct tun_struct *tun = netdev_priv(dev); + + strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); + strlcpy(info->version, DRV_VERSION, sizeof(info->version)); + + switch (tun->flags & TUN_TYPE_MASK) { + case TUN_TUN_DEV: + strlcpy(info->bus_info, "bf_tun", sizeof(info->bus_info)); + break; + case TUN_TAP_DEV: + strlcpy(info->bus_info, "tap", sizeof(info->bus_info)); + break; + } +} + +static u32 tun_get_msglevel(struct net_device *dev) +{ +#ifdef TUN_DEBUG + struct tun_struct *tun = netdev_priv(dev); + return tun->debug; +#else + return -EOPNOTSUPP; +#endif +} + +static void tun_set_msglevel(struct net_device *dev, u32 value) +{ +#ifdef TUN_DEBUG + struct tun_struct *tun = netdev_priv(dev); + tun->debug = value; +#endif +} + +static const struct ethtool_ops tun_ethtool_ops = { + .get_settings = tun_get_settings, + .get_drvinfo = tun_get_drvinfo, + .get_msglevel = tun_get_msglevel, + .set_msglevel = tun_set_msglevel, + .get_link = ethtool_op_get_link, + .get_ts_info = ethtool_op_get_ts_info, +}; + + +static int __init tun_init(void) +{ + int ret = 0; + + pr_info("%s, %s\n", DRV_DESCRIPTION, DRV_VERSION); + pr_info("%s\n", DRV_COPYRIGHT); + + ret = rtnl_link_register(&tun_link_ops); + if (ret) { + pr_err("Can't register link_ops\n"); + goto err_linkops; + } + + ret = misc_register(&tun_miscdev); + if (ret) { + pr_err("Can't register misc device %d\n", (TUN_MINOR1)); + goto err_misc; + } + return 0; +err_misc: + rtnl_link_unregister(&tun_link_ops); +err_linkops: + return ret; +} + +static void tun_cleanup(void) +{ + misc_deregister(&tun_miscdev); + rtnl_link_unregister(&tun_link_ops); +} + +/* Get an underlying socket object from tun file. Returns error unless file is + * attached to a device. The returned object works like a packet socket, it + * can be used for sock_sendmsg/sock_recvmsg. The caller is responsible for + * holding a reference to the file for as long as the socket is in use. */ +struct socket *bf_tun_get_socket(struct file *file) +{ + struct tun_file *tfile; + if (file->f_op != &tun_fops) + return ERR_PTR(-EINVAL); + tfile = file->private_data; + if (!tfile) + return ERR_PTR(-EBADFD); + return &tfile->socket; +} +EXPORT_SYMBOL_GPL(bf_tun_get_socket); + +module_init(tun_init); +module_exit(tun_cleanup); +MODULE_DESCRIPTION(DRV_DESCRIPTION); +MODULE_AUTHOR(DRV_COPYRIGHT); +MODULE_LICENSE("GPL"); +MODULE_ALIAS_MISCDEV(TUN_MINOR1); +MODULE_ALIAS("devname:net/bf_tun"); diff --git a/platform/barefoot/sonic-platform-modules-bfn/scripts/test b/platform/barefoot/sonic-platform-modules-bfn/scripts/test new file mode 100755 index 000000000000..38327722c91f --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-bfn/scripts/test @@ -0,0 +1 @@ +echo "test" diff --git a/sonic-slave/Dockerfile b/sonic-slave/Dockerfile index f194bf604caa..d1a7a8c8e5ae 100644 --- a/sonic-slave/Dockerfile +++ b/sonic-slave/Dockerfile @@ -114,6 +114,9 @@ RUN apt-get update && apt-get install -y \ # For mellanox sai build libtool-bin \ libxml2-dev \ +# For BFN sdk build + libusb-1.0-0-dev \ + libcurl3-nss-dev \ # For build image cpio \ squashfs-tools \ diff --git a/src/sonic-config-engine/tests/sample_output/interfaces b/src/sonic-config-engine/tests/sample_output/interfaces index 89a23471a7ee..5fb47380644b 100644 --- a/src/sonic-config-engine/tests/sample_output/interfaces +++ b/src/sonic-config-engine/tests/sample_output/interfaces @@ -15,6 +15,11 @@ iface lo inet6 static address fc00:1::32 netmask 128 # +# BMC interface +auto usb0 +iface usb0 inet static + address 192.168.0.2 + netmask 255.255.255.0 # The management network interface auto eth0 iface eth0 inet static diff --git a/src/sonic-sairedis b/src/sonic-sairedis index f5d9c8364f5f..aa5bf640db7b 160000 --- a/src/sonic-sairedis +++ b/src/sonic-sairedis @@ -1 +1 @@ -Subproject commit f5d9c8364f5fbcc487a5f1a3e3e6203ab2293a83 +Subproject commit aa5bf640db7b7fca245c1669eeb02198a50cb5c1 diff --git a/src/sonic-swss b/src/sonic-swss index e07d86b100cc..475e2da081e6 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit e07d86b100ccefe8b51e2c41b543cc93f33a0f13 +Subproject commit 475e2da081e600fca839a140af620a68c8206096 From 2247c9fcce8c47bac7db9548f5a57b45432421fb Mon Sep 17 00:00:00 2001 From: kram Date: Fri, 3 Nov 2017 11:49:06 -0700 Subject: [PATCH 02/58] update refpoint --- src/sonic-swss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-swss b/src/sonic-swss index 475e2da081e6..4a02a6f83192 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit 475e2da081e600fca839a140af620a68c8206096 +Subproject commit 4a02a6f8319271ec33b8ab1c595a17c5030508af From 161bf76c5bf9e508a9436df3dc189dc6113d0d3b Mon Sep 17 00:00:00 2001 From: kram Date: Fri, 3 Nov 2017 13:34:10 -0700 Subject: [PATCH 03/58] update refpoints --- src/sonic-sairedis | 2 +- src/sonic-swss | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sonic-sairedis b/src/sonic-sairedis index f5d9c8364f5f..29ab3de71f1e 160000 --- a/src/sonic-sairedis +++ b/src/sonic-sairedis @@ -1 +1 @@ -Subproject commit f5d9c8364f5fbcc487a5f1a3e3e6203ab2293a83 +Subproject commit 29ab3de71f1ec297fd0c79057a4fe5d34e4e62a5 diff --git a/src/sonic-swss b/src/sonic-swss index f90a4e1ef369..9aa837777004 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit f90a4e1ef369491b84a048cbf234f4cd3442d552 +Subproject commit 9aa837777004e68b79199d54ff64801d31ad9ea7 From 8f62271e2993ee462b6aa80641d65232f8ee02ce Mon Sep 17 00:00:00 2001 From: kram Date: Sat, 4 Nov 2017 14:15:04 -0700 Subject: [PATCH 04/58] update refpoints to bf-master --- src/sonic-sairedis | 2 +- src/sonic-swss | 2 +- src/sonic-swss-common | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sonic-sairedis b/src/sonic-sairedis index 29ab3de71f1e..bb9256a12ad2 160000 --- a/src/sonic-sairedis +++ b/src/sonic-sairedis @@ -1 +1 @@ -Subproject commit 29ab3de71f1ec297fd0c79057a4fe5d34e4e62a5 +Subproject commit bb9256a12ad27eb8f6dfeb01d1f43930b048323d diff --git a/src/sonic-swss b/src/sonic-swss index 9aa837777004..56d480e02c03 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit 9aa837777004e68b79199d54ff64801d31ad9ea7 +Subproject commit 56d480e02c033040e2e2394b24b0bc1e03f5e5da diff --git a/src/sonic-swss-common b/src/sonic-swss-common index 2e94b54e3626..adf7d4cb3c22 160000 --- a/src/sonic-swss-common +++ b/src/sonic-swss-common @@ -1 +1 @@ -Subproject commit 2e94b54e3626a4acd73bb3edb2f94d61793ee0e4 +Subproject commit adf7d4cb3c22061bf781ef6ce7b79964ce505730 From 0cd43aaa8304456945d0d05a7fd2c8e654020934 Mon Sep 17 00:00:00 2001 From: kram Date: Sat, 4 Nov 2017 14:30:44 -0700 Subject: [PATCH 05/58] update refpoint --- src/sonic-sairedis | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-sairedis b/src/sonic-sairedis index bb9256a12ad2..e0366e03b884 160000 --- a/src/sonic-sairedis +++ b/src/sonic-sairedis @@ -1 +1 @@ -Subproject commit bb9256a12ad27eb8f6dfeb01d1f43930b048323d +Subproject commit e0366e03b884b155bc93751999ae08b961592026 From ce851cbdc9f69e546333cc86ef16473ece70d7fc Mon Sep 17 00:00:00 2001 From: kram Date: Mon, 6 Nov 2017 15:40:23 -0800 Subject: [PATCH 06/58] update refpoint to tested version --- src/sonic-swss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-swss b/src/sonic-swss index 56d480e02c03..0011df48a906 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit 56d480e02c033040e2e2394b24b0bc1e03f5e5da +Subproject commit 0011df48a9062233b7eac9bb000dec5ae0d0bf0d From 8aa2359d2b9cd446b55cd65cdf247c41074b1167 Mon Sep 17 00:00:00 2001 From: kram Date: Tue, 7 Nov 2017 11:12:40 -0800 Subject: [PATCH 07/58] change to platform from asic --- dockers/docker-orchagent/orchagent.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/dockers/docker-orchagent/orchagent.sh b/dockers/docker-orchagent/orchagent.sh index b11a20223035..587909cd20b5 100755 --- a/dockers/docker-orchagent/orchagent.sh +++ b/dockers/docker-orchagent/orchagent.sh @@ -1,5 +1,8 @@ #!/usr/bin/env bash +ulimit -c unlimited +sysctl -w kernel.core_pattern=core + # Export platform information. Required to be able to write # vendor specific code. export platform=`sonic-cfggen -y /etc/sonic/sonic_version.yml -v asic_type` @@ -18,7 +21,7 @@ if [ "$platform" == "broadcom" ]; then ORCHAGENT_ARGS+="-m $MAC_ADDRESS" elif [ "$platform" == "cavium" ]; then ORCHAGENT_ARGS+="-m $MAC_ADDRESS" -elif [ "$ASIC" == "barefoot" ]; then +elif [ "$platform" == "barefoot" ]; then ORCHAGENT_ARGS+="-m $MAC_ADDRESS" fi From f5ec304b15b0e9ea5270c9779f637a3a0207b09a Mon Sep 17 00:00:00 2001 From: kram Date: Thu, 9 Nov 2017 15:37:12 -0800 Subject: [PATCH 08/58] update refpoint for swss --- src/sonic-swss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-swss b/src/sonic-swss index 0011df48a906..1b347a4337f7 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit 0011df48a9062233b7eac9bb000dec5ae0d0bf0d +Subproject commit 1b347a4337f77e5d166601fbabeaca4b32875f23 From 33a500470dd0c9f0d7c0a88ea70c991c7aa0a718 Mon Sep 17 00:00:00 2001 From: kram Date: Thu, 9 Nov 2017 18:33:16 -0800 Subject: [PATCH 09/58] revert core creation setting --- dockers/docker-orchagent/orchagent.sh | 3 - .../modules/bf_kdrv.c | 193 +++++++++++++----- 2 files changed, 145 insertions(+), 51 deletions(-) diff --git a/dockers/docker-orchagent/orchagent.sh b/dockers/docker-orchagent/orchagent.sh index 587909cd20b5..2bec34951e9b 100755 --- a/dockers/docker-orchagent/orchagent.sh +++ b/dockers/docker-orchagent/orchagent.sh @@ -1,8 +1,5 @@ #!/usr/bin/env bash -ulimit -c unlimited -sysctl -w kernel.core_pattern=core - # Export platform information. Required to be able to write # vendor specific code. export platform=`sonic-cfggen -y /etc/sonic/sonic_version.yml -v asic_type` diff --git a/platform/barefoot/sonic-platform-modules-bfn/modules/bf_kdrv.c b/platform/barefoot/sonic-platform-modules-bfn/modules/bf_kdrv.c index f486a4164470..5f084f6a040f 100644 --- a/platform/barefoot/sonic-platform-modules-bfn/modules/bf_kdrv.c +++ b/platform/barefoot/sonic-platform-modules-bfn/modules/bf_kdrv.c @@ -61,6 +61,7 @@ #include #include #include +#include #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 16, 0) //#error unsupported linux kernel version @@ -71,7 +72,8 @@ extern int pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec); extern int pci_enable_msix_range(struct pci_dev *dev, struct msix_entry *entries, int minvec, int maxvec); #define PCI_VENDOR_ID_BF 0x1d1c -#define TOFINO_DEV_ID 1 +#define TOFINO_DEV_ID_A0 0x01 +#define TOFINO_DEV_ID_B0 0x10 #ifndef PCI_MSIX_ENTRY_SIZE #define PCI_MSIX_ENTRY_SIZE 16 @@ -108,13 +110,19 @@ struct bf_dev_mem { void __iomem *internal_addr; }; +struct bf_listener { + struct bf_pci_dev *bfdev; + s32 event_count[BF_MSIX_ENTRY_CNT]; + int minor; + struct bf_listener *next; +}; + /* device information */ struct bf_dev_info { struct module *owner; struct device *dev; int minor; atomic_t event[BF_MSIX_ENTRY_CNT]; - struct fasync_struct *async_queue; wait_queue_head_t wait; const char *version; struct bf_dev_mem mem[BF_MAX_BAR_MAPS]; @@ -138,11 +146,21 @@ struct bf_int_vector { struct bf_pci_dev { struct bf_dev_info info; struct pci_dev *pdev; - struct cdev cdev; enum bf_intr_mode mode; u8 instance; char name[16]; struct bf_int_vector bf_int_vec[BF_MSIX_ENTRY_CNT]; + struct bf_listener *listener_head; /* head of a singly linked list of + listeners */ +}; + +/* Keep any global information here that must survive even after the + * bf_pci_dev is free-ed up. + */ +struct bf_global { + struct bf_pci_dev *bfdev ; + struct cdev *bf_cdev; + struct fasync_struct *async_queue; }; static int bf_major; @@ -151,6 +169,55 @@ static struct class *bf_class = NULL; static char *intr_mode = NULL; static enum bf_intr_mode bf_intr_mode_default = BF_INTR_MODE_MSI; static spinlock_t bf_nonisr_lock; +/* dev->minor should index into this array */ +static struct bf_global bf_global[BF_MAX_DEVICE_CNT]; + +static void bf_add_listener(struct bf_pci_dev *bfdev, + struct bf_listener *listener) +{ + struct bf_listener **cur_listener = &bfdev->listener_head; + + if (!listener) { + return; + } + spin_lock(&bf_nonisr_lock); + + while (*cur_listener) { + cur_listener = &((*cur_listener)->next); + } + *cur_listener = listener; + listener->next = NULL; + + spin_unlock(&bf_nonisr_lock); +} + +static void bf_remove_listener(struct bf_pci_dev *bfdev, + struct bf_listener *listener) +{ + struct bf_listener **cur_listener = &bfdev->listener_head; + + /* in case of certain error conditions, this function might be called after bf_pci_remove() + */ + if (!bfdev || !listener) { + return; + } + spin_lock(&bf_nonisr_lock); + + if (*cur_listener == listener) { + *cur_listener = listener->next; + } else { + while (*cur_listener) { + if ((*cur_listener)->next == listener) { + (*cur_listener)->next = listener->next; + break; + } + cur_listener = &((*cur_listener)->next); + } + listener->next = NULL; + } + + spin_unlock(&bf_nonisr_lock); +} /* a pool of minor numbers is maintained */ /* return the first available minor number */ @@ -345,17 +412,15 @@ static irqreturn_t bf_interrupt(int irq, void *bfdev_id) return ret; } -struct bf_listener { - struct bf_pci_dev *bfdev; - s32 event_count[BF_MSIX_ENTRY_CNT]; -}; - static unsigned int bf_poll(struct file *filep, poll_table *wait) { struct bf_listener *listener = (struct bf_listener *)filep->private_data; struct bf_pci_dev *bfdev = listener->bfdev; int i; + if (!bfdev) { + return -ENODEV; + } if (!bfdev->info.irq) return -EIO; @@ -422,6 +487,9 @@ static int bf_mmap(struct file *filep, struct vm_area_struct *vma) int bar; unsigned long requested_pages, actual_pages; + if (!bfdev) { + return -ENODEV; + } if (vma->vm_end < vma->vm_start) return -EINVAL; @@ -442,12 +510,19 @@ static int bf_mmap(struct file *filep, struct vm_area_struct *vma) static int bf_fasync(int fd, struct file *filep, int mode) { - struct bf_pci_dev *bfdev = ((struct bf_listener *)filep->private_data)->bfdev; + int minor; - if (mode == 0 && &bfdev->info.async_queue == NULL) { + if (!filep->private_data) { + return (-EINVAL); + } + minor = ((struct bf_listener *)filep->private_data)->minor; + if (minor >= BF_MAX_DEVICE_CNT) { + return (-EINVAL); + } + if (mode == 0 && &bf_global[minor].async_queue == NULL) { return 0; /* nothing to do */ } - return (fasync_helper(fd, filep, mode, &bfdev->info.async_queue)); + return (fasync_helper(fd, filep, mode, &bf_global[minor].async_queue)); } static int bf_open(struct inode *inode, struct file *filep) @@ -456,10 +531,13 @@ static int bf_open(struct inode *inode, struct file *filep) struct bf_listener *listener; int i; - bfdev = container_of(inode->i_cdev, struct bf_pci_dev, cdev); + bfdev = bf_global[iminor(inode)].bfdev; listener = kmalloc(sizeof(*listener), GFP_KERNEL); if (listener) { listener->bfdev = bfdev; + listener->minor = bfdev->info.minor; + listener->next = NULL; + bf_add_listener(bfdev, listener); for (i = 0; i < BF_MSIX_ENTRY_CNT; i++) listener->event_count[i] = atomic_read(&bfdev->info.event[i]); filep->private_data = listener; @@ -474,6 +552,9 @@ static int bf_release(struct inode *inode, struct file *filep) struct bf_listener *listener = filep->private_data; bf_fasync(-1, filep, 0); /* empty any process id in the notification list */ + if (listener->bfdev) { + bf_remove_listener(listener->bfdev, listener); + } kfree(listener); return 0; } @@ -488,6 +569,9 @@ static ssize_t bf_read(struct file *filep, char __user *buf, int i, mismatch_found = 0; /* OR of per vector mismatch */ unsigned char cnt_match[BF_MSIX_ENTRY_CNT]; /* per vector mismatch */ + if (!bfdev) { + return -ENODEV; + } /* irq must be setup for read() to work */ if (!bfdev->info.irq) return -EIO; @@ -593,8 +677,9 @@ static const struct file_operations bf_fops = { .fasync = bf_fasync, }; -static int bf_major_init(struct bf_pci_dev *bfdev) +static int bf_major_init(struct bf_pci_dev *bfdev, int minor) { + struct cdev *cdev; static const char name[] = "bf"; dev_t bf_dev = 0; int result; @@ -604,26 +689,20 @@ static int bf_major_init(struct bf_pci_dev *bfdev) return result; result = -ENOMEM; -/* following code useful if we chose to allocate cdev here - * - *struct cdev *cdev = NULL; - * cdev = cdev_alloc(); - * if (!cdev) - * goto fail_unregister; - * cdev->ops = &bf_fops; - * cdev->owner = THIS_MODULE; - * kobject_set_name(&cdev->kobj, "%s", name); - * result = cdev_add(cdev, bf_dev, BF_MAX_DEVICE_CNT); - */ - cdev_init(&bfdev->cdev, &bf_fops); - bfdev->cdev.owner = THIS_MODULE; - bfdev->cdev.ops = &bf_fops; + cdev = cdev_alloc(); + if (!cdev) { + goto fail_dev_add; + } + cdev->ops = &bf_fops; + cdev->owner = THIS_MODULE; + kobject_set_name(&cdev->kobj, "%s", name); + result = cdev_add(cdev, bf_dev, BF_MAX_DEVICE_CNT); - result = cdev_add(&bfdev->cdev, bf_dev, BF_MAX_DEVICE_CNT); if (result) goto fail_dev_add; bf_major = MAJOR(bf_dev); + bf_global[minor].bf_cdev = cdev; return 0; fail_dev_add: @@ -631,16 +710,16 @@ static int bf_major_init(struct bf_pci_dev *bfdev) return result; } -static void bf_major_cleanup(struct bf_pci_dev *bfdev) +static void bf_major_cleanup(struct bf_pci_dev *bfdev, int minor) { unregister_chrdev_region(MKDEV(bf_major, 0), BF_MAX_DEVICE_CNT); - cdev_del(&bfdev->cdev); + cdev_del(bf_global[minor].bf_cdev); } -static int bf_init_cdev(struct bf_pci_dev *bfdev) +static int bf_init_cdev(struct bf_pci_dev *bfdev, int minor) { int ret; - ret = bf_major_init(bfdev); + ret = bf_major_init(bfdev, minor); if (ret) return ret; @@ -653,14 +732,14 @@ static int bf_init_cdev(struct bf_pci_dev *bfdev) return 0; err_class_register: - bf_major_cleanup(bfdev); + bf_major_cleanup(bfdev, minor); return ret; } static void bf_remove_cdev(struct bf_pci_dev *bfdev) { class_destroy(bf_class); - bf_major_cleanup(bfdev); + bf_major_cleanup(bfdev, bfdev->info.minor); } @@ -686,16 +765,16 @@ int bf_register_device(struct device *parent, struct bf_pci_dev *bfdev) atomic_set(&info->event[i], 0); } - ret = bf_init_cdev(bfdev); + if (bf_get_next_minor_no(&minor)) { + return -EINVAL; + } + + ret = bf_init_cdev(bfdev, minor); if (ret) { printk(KERN_ERR "BF: device cdev creation failed\n"); return ret; } - if (bf_get_next_minor_no(&minor)) { - return -EINVAL; - } - info->dev = device_create(bf_class, parent, MKDEV(bf_major, minor), bfdev, "bf%d", minor); @@ -806,6 +885,8 @@ bf_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) int err, pci_use_highmem; int i, num_irq; + memset(bf_global, 0, sizeof(bf_global)); + bfdev = kzalloc(sizeof(struct bf_pci_dev), GFP_KERNEL); if (!bfdev) return -ENOMEM; @@ -816,8 +897,6 @@ bf_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) bfdev->bf_int_vec[i].bf_dev = bfdev; } - bfdev->info.async_queue = NULL; - /* initialize intr_mode to none */ bfdev->mode = BF_INTR_MODE_NONE; @@ -953,12 +1032,15 @@ bf_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) goto fail_clear_pci_master; } + pci_set_drvdata(pdev, bfdev); + sprintf(bfdev->name, "bf_%d", bfdev->info.minor); /* register bf driver */ err = bf_register_device(&pdev->dev, bfdev); if (err != 0) goto fail_release_irq; - sprintf(bfdev->name, "bf_%d", bfdev->info.minor); - pci_set_drvdata(pdev, bfdev); + + bf_global[bfdev->info.minor].async_queue = NULL; + bf_global[bfdev->info.minor].bfdev = bfdev; dev_info(&pdev->dev, "bf device %d registered with irq %ld\n", bfdev->instance, bfdev->info.irq); @@ -966,6 +1048,7 @@ bf_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) return 0; fail_release_irq: + pci_set_drvdata(pdev, NULL); if (bfdev->mode == BF_INTR_MODE_MSIX) { pci_disable_msix(bfdev->pdev); kfree(bfdev->info.msix_entries); @@ -991,6 +1074,7 @@ static void bf_pci_remove(struct pci_dev *pdev) { struct bf_pci_dev *bfdev = pci_get_drvdata(pdev); + struct bf_listener *cur_listener; bf_unregister_device(bfdev); if (bfdev->mode == BF_INTR_MODE_MSIX) { @@ -1006,6 +1090,16 @@ bf_pci_remove(struct pci_dev *pdev) pci_disable_pcie_error_reporting(pdev); pci_disable_device(pdev); pci_set_drvdata(pdev, NULL); + bf_global[bfdev->info.minor].bfdev = NULL; + /* existing filep structures in open file(s) must be informed that + * bf_pci_dev is no longer valid */ + spin_lock(&bf_nonisr_lock); + cur_listener = bfdev->listener_head; + while (cur_listener) { + cur_listener->bfdev = NULL; + cur_listener = cur_listener->next; + } + spin_unlock(&bf_nonisr_lock); kfree(bfdev); } @@ -1020,16 +1114,18 @@ static pci_ers_result_t bf_pci_error_detected(struct pci_dev *pdev, pci_channel_state_t state) { struct bf_pci_dev *bfdev = pci_get_drvdata(pdev); + int minor; if (!bfdev) { return PCI_ERS_RESULT_NONE; } - printk(KERN_ERR "pci_err_detected state %d asyncQ %p\n", state, &bfdev->info.async_queue); + printk(KERN_ERR "pci_err_detected state %d\n", state); if (state == pci_channel_io_perm_failure || state == pci_channel_io_frozen) { bfdev->info.pci_error_state = 1; /* send a signal to the user space program of the error */ - if (bfdev->info.async_queue) { - kill_fasync(&bfdev->info.async_queue, SIGIO, POLL_ERR); + minor = bfdev->info.minor; + if (minor < BF_MAX_DEVICE_CNT && bf_global[minor].async_queue) { + kill_fasync(&bf_global[minor].async_queue, SIGIO, POLL_ERR); } return PCI_ERS_RESULT_DISCONNECT; } else { @@ -1096,7 +1192,8 @@ bf_config_intr_mode(char *intr_str) } static const struct pci_device_id bf_pci_tbl[] = { - {PCI_VDEVICE(BF, TOFINO_DEV_ID), 0}, + {PCI_VDEVICE(BF, TOFINO_DEV_ID_A0), 0}, + {PCI_VDEVICE(BF, TOFINO_DEV_ID_B0), 0}, /* required last entry */ { .device = 0 } }; @@ -1140,7 +1237,7 @@ module_exit(bfdrv_exit); module_param(intr_mode, charp, S_IRUGO); MODULE_PARM_DESC(intr_mode, -"bf interrupt mode (default=msi):\n" +"bf interrupt mode (default=msix):\n" " " BF_INTR_MODE_MSIX_NAME " Use MSIX interrupt\n" " " BF_INTR_MODE_MSI_NAME " Use MSI interrupt\n" " " BF_INTR_MODE_LEGACY_NAME " Use Legacy interrupt\n" From aacc252dbfaab3b344700e2bae14663884be4c2f Mon Sep 17 00:00:00 2001 From: kram Date: Wed, 15 Nov 2017 13:28:35 -0800 Subject: [PATCH 10/58] update refpoints --- src/sonic-sairedis | 2 +- src/sonic-swss | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sonic-sairedis b/src/sonic-sairedis index 62dea03d74a4..30c8f899f1c9 160000 --- a/src/sonic-sairedis +++ b/src/sonic-sairedis @@ -1 +1 @@ -Subproject commit 62dea03d74a49716a6647e3fa3a3654b19bf46ad +Subproject commit 30c8f899f1c9919859eb7005705ee7fba05f9ac2 diff --git a/src/sonic-swss b/src/sonic-swss index 01899cdc33df..8c1d48840c99 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit 01899cdc33df5dc9ae95bf6bd09979a08e620035 +Subproject commit 8c1d48840c999e8e31fee409b42740dac06e6769 From bea422b2f1a02c12e9026d972e310dfeb16410a0 Mon Sep 17 00:00:00 2001 From: kram Date: Fri, 17 Nov 2017 13:39:17 -0800 Subject: [PATCH 11/58] add telnet for debug shell --- sonic-slave/Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/sonic-slave/Dockerfile b/sonic-slave/Dockerfile index 435dd7da0206..1e9a2978389f 100644 --- a/sonic-slave/Dockerfile +++ b/sonic-slave/Dockerfile @@ -117,6 +117,7 @@ RUN apt-get update && apt-get install -y \ # For BFN sdk build libusb-1.0-0-dev \ libcurl3-nss-dev \ + telnet \ # For build image cpio \ squashfs-tools \ From a848be6bffb1a81b99fa5479e241555f15a34263 Mon Sep 17 00:00:00 2001 From: kram Date: Fri, 17 Nov 2017 18:40:32 -0800 Subject: [PATCH 12/58] update refpoints 11/17/17 --- src/sonic-sairedis | 2 +- src/sonic-swss | 2 +- src/sonic-swss-common | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sonic-sairedis b/src/sonic-sairedis index 30c8f899f1c9..67d998bb7e1b 160000 --- a/src/sonic-sairedis +++ b/src/sonic-sairedis @@ -1 +1 @@ -Subproject commit 30c8f899f1c9919859eb7005705ee7fba05f9ac2 +Subproject commit 67d998bb7e1bf2845cc9238adc438d1f215750c0 diff --git a/src/sonic-swss b/src/sonic-swss index 8c1d48840c99..c9446922a8a4 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit 8c1d48840c999e8e31fee409b42740dac06e6769 +Subproject commit c9446922a8a4e9fb760d0d4b77760826fbbd1974 diff --git a/src/sonic-swss-common b/src/sonic-swss-common index be508cff8947..a67ee684ed33 160000 --- a/src/sonic-swss-common +++ b/src/sonic-swss-common @@ -1 +1 @@ -Subproject commit be508cff8947cf07a712d21afe2ae80238ccc483 +Subproject commit a67ee684ed33083f61df83cd1ba9c047e5ed8b68 From e4131ca7b10e7adcde42f1e3e53f22f68dfb8354 Mon Sep 17 00:00:00 2001 From: kram Date: Mon, 20 Nov 2017 16:48:05 -0800 Subject: [PATCH 13/58] missed change in file on previous merge --- platform/barefoot/one-image.mk | 2 -- 1 file changed, 2 deletions(-) diff --git a/platform/barefoot/one-image.mk b/platform/barefoot/one-image.mk index 52cc9ba369aa..c7072d9b4492 100644 --- a/platform/barefoot/one-image.mk +++ b/platform/barefoot/one-image.mk @@ -5,7 +5,5 @@ $(SONIC_ONE_IMAGE)_MACHINE = barefoot $(SONIC_ONE_IMAGE)_IMAGE_TYPE = onie $(SONIC_ONE_IMAGE)_INSTALLS += $(BFN_PLATFORM_MODULE) $(SONIC_ONE_IMAGE)_INSTALLS += $(BFN_MONTARA_PLATFORM_MODULE) -$(SONIC_ONE_IMAGE)_DEPENDS += $(BFN_PLATFORM_MODULE) -$(SONIC_ONE_IMAGE)_DEPENDS += $(BFN_MONTARA_PLATFORM_MODULE) $(SONIC_ONE_IMAGE)_DOCKERS += $(SONIC_INSTALL_DOCKER_IMAGES) SONIC_INSTALLERS += $(SONIC_ONE_IMAGE) From ee659f06f6f5a7ae59b5861eee29c560c6efd803 Mon Sep 17 00:00:00 2001 From: kram Date: Tue, 12 Dec 2017 20:07:42 -0800 Subject: [PATCH 14/58] merge with Azure master (12/12/17) --- build_debian.sh | 2 + .../Accton-AS5712-54X/port_config.ini | 147 +- .../Accton-AS5712-54X/sai.profile | 1 - .../x86_64-accton_as5712_54x-r0/minigraph.xml | 1235 ++++++++++++- .../plugins/sfputil.py | 215 ++- .../plugins/sfputil.py | 70 +- .../Arista-7050-QX32/qos.json | 156 ++ .../plugins/psuutil.py | 12 + .../x86_64-arista_7050_qx32/sensors.conf | 18 +- .../plugins/psuutil.py | 12 + .../plugins/psuutil.py | 12 + .../x86_64-arista_7060_cx32s/sensors.conf | 29 +- .../plugins/psuutil.py | 12 + .../x86_64-arista_7260cx3_64/sensors.conf | 20 +- .../Force10-S6000/qos.json | 156 ++ .../Force10-S6100/qos.json | 156 ++ .../plugins/psuutil.py | 80 + .../plugins/psuutil.py | 80 + .../Delta-ag9032v1/port_config.ini | 33 + .../Delta-ag9032v1/sai.profile | 1 + .../delta/x86_64-delta_ag9032v1-r0/fancontrol | 10 + .../fancontrol.service | 244 +++ .../x86_64-delta_ag9032v1-r0/installer.conf | 2 + .../led_proc_init.soc | 45 + .../x86_64-delta_ag9032v1-r0/minigraph.xml | 1079 ++++++++++++ .../plugins/eeprom.py | 32 + .../plugins/sfputil.py | 175 ++ .../x86_64-delta_ag9032v1-r0/sensors.conf | 61 + .../minigraph.xml | 4 +- .../x86_64-ingrasys_s8810_32q-r0/sensors.conf | 4 +- .../INGRASYS-S8900-54XC/port_config.ini | 108 +- .../INGRASYS-S8900-64XC/port_config.ini | 96 +- .../INGRASYS-S9200-64X/port_config.ini | 65 + .../INGRASYS-S9200-64X/sai.profile | 1 + .../x86_64-ingrasys_s9200_64x-r0/fancontrol | 9 + .../installer.conf | 3 + .../led_proc_init.soc | 111 ++ .../minigraph.xml | 151 ++ .../plugins/eeprom.py | 24 + .../plugins/sfputil.py | 260 +++ .../x86_64-ingrasys_s9200_64x-r0/sensors.conf | 68 + .../x86_64-mlnx_msn2100-r0/plugins/psuutil.py | 64 + .../x86_64-mlnx_msn2410-r0/plugins/psuutil.py | 74 + .../ACS-MSN2700/qos.json | 166 ++ .../x86_64-mlnx_msn2700-r0/Mellanox-SN2700 | 1 + .../x86_64-mlnx_msn2700-r0/plugins/psuutil.py | 74 + .../ACS-MSN2740/qos.json | 1 + .../x86_64-mlnx_msn2740-r0/plugins/psuutil.py | 74 + dockers/docker-database/Dockerfile.j2 | 2 +- dockers/docker-dhcp-relay/start.sh | 7 +- dockers/docker-dhcp-relay/wait_for_intf.sh.j2 | 31 +- dockers/docker-fpm-frr/bgpd.conf.j2 | 7 +- dockers/docker-fpm-quagga/start.sh | 8 +- dockers/docker-lldp-sv2/lldpd.conf.j2 | 1 + dockers/docker-orchagent/Dockerfile.j2 | 3 +- .../msn27xx.32ports.buffers.json.j2 | 8 +- dockers/docker-orchagent/ports.json.j2 | 3 +- dockers/docker-orchagent/start.sh | 6 +- dockers/docker-orchagent/swssconfig.sh | 6 +- dockers/docker-ptf/Dockerfile.j2 | 4 + dockers/docker-snmp-sv2/Dockerfile.j2 | 1 + files/Aboot/boot0.j2 | 17 +- .../build_templates/sonic_debian_extension.j2 | 13 + .../hostname/hostname-config.service | 11 + .../image_config/hostname/hostname-config.sh | 11 + files/image_config/platform/rc.local | 6 + .../updategraph/updategraph.service | 1 + files/initramfs-tools/arista-convertfs.j2 | 3 + files/initramfs-tools/setfacl | 20 + .../scripts}/arp_update | 0 .../scripts}/configdb-load.sh | 0 platform/barefoot/docker-orchagent-bfn.mk | 1 + platform/broadcom/docker-orchagent-brcm.mk | 1 + platform/broadcom/one-image.mk | 5 +- platform/broadcom/platform-modules-accton.mk | 10 +- platform/broadcom/platform-modules-delta.mk | 12 + .../broadcom/platform-modules-ingrasys.mk | 6 + platform/broadcom/rules.mk | 1 + platform/broadcom/sai.mk | 8 +- platform/broadcom/sdk.mk | 4 +- .../broadcom/sonic-platform-modules-accton | 2 +- .../broadcom/sonic-platform-modules-arista | 2 +- .../sonic-platform-modules-delta/LICENSE | 16 + .../ag9032v1/cfg/ag9032v1-modules.conf | 13 + .../ag9032v1/modules/Makefile | 2 + .../ag9032v1/modules/at24.c | 698 ++++++++ .../modules/delta_ag9032v1_platform.c | 1530 +++++++++++++++++ .../ag9032v1/modules/dni_ag9032v1_psu.c | 545 ++++++ .../ag9032v1/modules/dni_emc2305.c | 381 ++++ .../scripts/ag9032v1_platform_init.sh | 9 + .../ag9032v1/scripts/led_status.sh | 225 +++ .../debian/changelog | 5 + .../debian/compat | 1 + .../debian/control | 11 + .../sonic-platform-modules-delta/debian/files | 1 + .../debian/platform-modules-ag9032v1.init | 49 + .../debian/platform-modules-ag9032v1.install | 3 + .../sonic-platform-modules-delta/debian/rules | 33 + .../broadcom/sonic-platform-modules-ingrasys | 2 +- platform/cavium/docker-orchagent-cavm.mk | 1 + platform/centec/docker-orchagent-centec.mk | 1 + platform/marvell/docker-orchagent-mrvl.mk | 1 + platform/mellanox/docker-orchagent-mlnx.mk | 1 + platform/mellanox/fw.mk | 2 +- platform/mellanox/mlnx-sai.mk | 2 +- platform/mellanox/sdk.mk | 12 +- platform/vs/docker-sonic-vs.mk | 14 +- platform/vs/docker-sonic-vs/Dockerfile.j2 | 18 +- platform/vs/docker-sonic-vs/sonic-dev.gpg.key | 30 + platform/vs/docker-sonic-vs/start.sh | 32 +- platform/vs/docker-sonic-vs/supervisord.conf | 30 +- rules/asyncsnmp-py3.mk | 3 +- rules/docker-database.mk | 1 + rules/iproute2.mk | 7 + rules/linux-kernel.mk | 4 +- rules/scripts.mk | 11 + rules/sonic-utilities.mk | 8 + rules/tacacs.mk | 29 + slave.mk | 8 +- sonic-slave/Dockerfile | 19 +- src/iproute2/Makefile | 20 + src/sonic-config-engine/minigraph.py | 16 +- src/sonic-config-engine/sonic-cfggen | 11 +- .../tests/sample_output/lldpd.conf | 1 + .../tests/sample_output/msn27.32ports.json | 8 +- .../tests/sample_output/ports.json | 30 + .../tests/simple-sample-graph.xml | 2 + src/sonic-config-engine/tests/test_cfggen.py | 2 +- src/sonic-config-engine/tests/test_j2files.py | 7 + src/sonic-linux-kernel | 2 +- src/sonic-py-swsssdk | 2 +- src/sonic-sairedis | 2 +- src/sonic-swss | 2 +- src/sonic-swss-common | 2 +- src/sonic-utilities | 2 +- .../nss/0001-Modify-user-map-profile.patch | 1459 ++++++++++++++++ src/tacacs/nss/Makefile | 22 + ...on-t-init-declarations-in-a-for-loop.patch | 45 + ...-libtac2-bin-install-directory-error.patch | 19 + src/tacacs/pam/Makefile | 25 + 140 files changed, 10633 insertions(+), 478 deletions(-) mode change 100644 => 100755 device/accton/x86_64-accton_as5712_54x-r0/Accton-AS5712-54X/port_config.ini mode change 100644 => 100755 device/accton/x86_64-accton_as5712_54x-r0/Accton-AS5712-54X/sai.profile mode change 100644 => 100755 device/accton/x86_64-accton_as5712_54x-r0/minigraph.xml mode change 100644 => 100755 device/accton/x86_64-accton_as5712_54x-r0/plugins/sfputil.py create mode 100644 device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/qos.json create mode 100644 device/arista/x86_64-arista_7050_qx32/plugins/psuutil.py create mode 100644 device/arista/x86_64-arista_7050_qx32s/plugins/psuutil.py create mode 100644 device/arista/x86_64-arista_7060_cx32s/plugins/psuutil.py create mode 100644 device/arista/x86_64-arista_7260cx3_64/plugins/psuutil.py create mode 100644 device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000/qos.json create mode 100644 device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/qos.json create mode 100644 device/dell/x86_64-dell_s6100_c2538-r0/plugins/psuutil.py create mode 100644 device/dell/x86_64-dell_z9100_c2538-r0/plugins/psuutil.py create mode 100644 device/delta/x86_64-delta_ag9032v1-r0/Delta-ag9032v1/port_config.ini create mode 100644 device/delta/x86_64-delta_ag9032v1-r0/Delta-ag9032v1/sai.profile create mode 100644 device/delta/x86_64-delta_ag9032v1-r0/fancontrol create mode 100755 device/delta/x86_64-delta_ag9032v1-r0/fancontrol.service create mode 100644 device/delta/x86_64-delta_ag9032v1-r0/installer.conf create mode 100644 device/delta/x86_64-delta_ag9032v1-r0/led_proc_init.soc create mode 100644 device/delta/x86_64-delta_ag9032v1-r0/minigraph.xml create mode 100644 device/delta/x86_64-delta_ag9032v1-r0/plugins/eeprom.py create mode 100644 device/delta/x86_64-delta_ag9032v1-r0/plugins/sfputil.py create mode 100644 device/delta/x86_64-delta_ag9032v1-r0/sensors.conf create mode 100644 device/ingrasys/x86_64-ingrasys_s9200_64x-r0/INGRASYS-S9200-64X/port_config.ini create mode 100644 device/ingrasys/x86_64-ingrasys_s9200_64x-r0/INGRASYS-S9200-64X/sai.profile create mode 100644 device/ingrasys/x86_64-ingrasys_s9200_64x-r0/fancontrol create mode 100644 device/ingrasys/x86_64-ingrasys_s9200_64x-r0/installer.conf create mode 100644 device/ingrasys/x86_64-ingrasys_s9200_64x-r0/led_proc_init.soc create mode 100644 device/ingrasys/x86_64-ingrasys_s9200_64x-r0/minigraph.xml create mode 100644 device/ingrasys/x86_64-ingrasys_s9200_64x-r0/plugins/eeprom.py create mode 100644 device/ingrasys/x86_64-ingrasys_s9200_64x-r0/plugins/sfputil.py create mode 100644 device/ingrasys/x86_64-ingrasys_s9200_64x-r0/sensors.conf create mode 100644 device/mellanox/x86_64-mlnx_msn2100-r0/plugins/psuutil.py create mode 100644 device/mellanox/x86_64-mlnx_msn2410-r0/plugins/psuutil.py create mode 100644 device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/qos.json create mode 120000 device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700 create mode 100644 device/mellanox/x86_64-mlnx_msn2700-r0/plugins/psuutil.py create mode 120000 device/mellanox/x86_64-mlnx_msn2740-r0/ACS-MSN2740/qos.json create mode 100644 device/mellanox/x86_64-mlnx_msn2740-r0/plugins/psuutil.py create mode 100644 files/image_config/hostname/hostname-config.service create mode 100755 files/image_config/hostname/hostname-config.sh create mode 100644 files/initramfs-tools/setfacl rename {dockers/docker-orchagent => files/scripts}/arp_update (100%) rename {dockers/docker-database => files/scripts}/configdb-load.sh (100%) mode change 100644 => 100755 platform/broadcom/one-image.mk mode change 100644 => 100755 platform/broadcom/platform-modules-accton.mk create mode 100644 platform/broadcom/platform-modules-delta.mk create mode 100644 platform/broadcom/sonic-platform-modules-delta/LICENSE create mode 100644 platform/broadcom/sonic-platform-modules-delta/ag9032v1/cfg/ag9032v1-modules.conf create mode 100644 platform/broadcom/sonic-platform-modules-delta/ag9032v1/modules/Makefile create mode 100644 platform/broadcom/sonic-platform-modules-delta/ag9032v1/modules/at24.c create mode 100644 platform/broadcom/sonic-platform-modules-delta/ag9032v1/modules/delta_ag9032v1_platform.c create mode 100644 platform/broadcom/sonic-platform-modules-delta/ag9032v1/modules/dni_ag9032v1_psu.c create mode 100644 platform/broadcom/sonic-platform-modules-delta/ag9032v1/modules/dni_emc2305.c create mode 100755 platform/broadcom/sonic-platform-modules-delta/ag9032v1/scripts/ag9032v1_platform_init.sh create mode 100755 platform/broadcom/sonic-platform-modules-delta/ag9032v1/scripts/led_status.sh create mode 100644 platform/broadcom/sonic-platform-modules-delta/debian/changelog create mode 100644 platform/broadcom/sonic-platform-modules-delta/debian/compat create mode 100644 platform/broadcom/sonic-platform-modules-delta/debian/control create mode 100644 platform/broadcom/sonic-platform-modules-delta/debian/files create mode 100755 platform/broadcom/sonic-platform-modules-delta/debian/platform-modules-ag9032v1.init create mode 100644 platform/broadcom/sonic-platform-modules-delta/debian/platform-modules-ag9032v1.install create mode 100644 platform/broadcom/sonic-platform-modules-delta/debian/rules create mode 100644 platform/vs/docker-sonic-vs/sonic-dev.gpg.key create mode 100644 rules/iproute2.mk create mode 100644 rules/scripts.mk create mode 100644 rules/tacacs.mk create mode 100644 src/iproute2/Makefile create mode 100644 src/sonic-config-engine/tests/sample_output/ports.json create mode 100644 src/tacacs/nss/0001-Modify-user-map-profile.patch create mode 100644 src/tacacs/nss/Makefile create mode 100644 src/tacacs/pam/0001-Don-t-init-declarations-in-a-for-loop.patch create mode 100644 src/tacacs/pam/0002-Fix-libtac2-bin-install-directory-error.patch create mode 100644 src/tacacs/pam/Makefile diff --git a/build_debian.sh b/build_debian.sh index 3c6673a53ec4..0c765fdb6424 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -123,6 +123,8 @@ sudo cp files/initramfs-tools/arista-convertfs $FILESYSTEM_ROOT/etc/initramfs-to sudo chmod +x $FILESYSTEM_ROOT/etc/initramfs-tools/scripts/init-premount/arista-convertfs sudo cp files/initramfs-tools/mke2fs $FILESYSTEM_ROOT/etc/initramfs-tools/hooks/mke2fs sudo chmod +x $FILESYSTEM_ROOT/etc/initramfs-tools/hooks/mke2fs +sudo cp files/initramfs-tools/setfacl $FILESYSTEM_ROOT/etc/initramfs-tools/hooks/setfacl +sudo chmod +x $FILESYSTEM_ROOT/etc/initramfs-tools/hooks/setfacl # Hook into initramfs: rename the management interfaces on arista switches sudo cp files/initramfs-tools/arista-net $FILESYSTEM_ROOT/etc/initramfs-tools/scripts/init-premount/arista-net diff --git a/device/accton/x86_64-accton_as5712_54x-r0/Accton-AS5712-54X/port_config.ini b/device/accton/x86_64-accton_as5712_54x-r0/Accton-AS5712-54X/port_config.ini old mode 100644 new mode 100755 index 61325e1ec43c..f41bf2ef648f --- a/device/accton/x86_64-accton_as5712_54x-r0/Accton-AS5712-54X/port_config.ini +++ b/device/accton/x86_64-accton_as5712_54x-r0/Accton-AS5712-54X/port_config.ini @@ -1,74 +1,73 @@ -# name lanes alias -Ethernet0 13 tenGigE0 -Ethernet1 14 tenGigE1 -Ethernet2 15 tenGigE2 -Ethernet3 16 tenGigE3 -Ethernet4 21 tenGigE4 -Ethernet5 22 tenGigE5 -Ethernet6 23 tenGigE6 -Ethernet7 24 tenGigE7 -Ethernet8 25 tenGigE8 -Ethernet9 26 tenGigE9 -Ethernet10 27 tenGigE10 -Ethernet11 28 tenGigE11 -Ethernet12 29 tenGigE12 -Ethernet13 30 tenGigE13 -Ethernet14 31 tenGigE14 -Ethernet15 32 tenGigE15 -Ethernet16 45 tenGigE16 -Ethernet17 46 tenGigE17 -Ethernet18 47 tenGigE18 -Ethernet19 48 tenGigE19 -Ethernet20 49 tenGigE20 -Ethernet21 50 tenGigE21 -Ethernet22 51 tenGigE22 -Ethernet23 52 tenGigE23 -Ethernet24 53 tenGigE24 -Ethernet25 54 tenGigE25 -Ethernet26 55 tenGigE26 -Ethernet27 56 tenGigE27 -Ethernet28 57 tenGigE28 -Ethernet29 58 tenGigE29 -Ethernet30 59 tenGigE30 -Ethernet31 60 tenGigE31 -Ethernet32 61 tenGigE32 -Ethernet33 62 tenGigE33 -Ethernet34 63 tenGigE34 -Ethernet35 64 tenGigE35 -Ethernet36 65 tenGigE36 -Ethernet37 66 tenGigE37 -Ethernet38 67 tenGigE38 -Ethernet39 68 tenGigE39 -Ethernet40 69 tenGigE40 -Ethernet41 70 tenGigE41 -Ethernet42 71 tenGigE42 -Ethernet43 72 tenGigE43 -Ethernet44 73 tenGigE44 -Ethernet45 74 tenGigE45 -Ethernet46 75 tenGigE46 -Ethernet47 76 tenGigE47 -Ethernet48 97 tenGigE48 -Ethernet49 98 tenGigE49 -Ethernet50 99 tenGigE50 -Ethernet51 100 tenGigE51 -Ethernet52 101 tenGigE52 -Ethernet53 102 tenGigE53 -Ethernet54 103 tenGigE54 -Ethernet55 104 tenGigE55 -Ethernet56 81 tenGigE56 -Ethernet57 82 tenGigE57 -Ethernet58 83 tenGigE58 -Ethernet59 84 tenGigE59 -Ethernet60 105 tenGigE60 -Ethernet61 106 tenGigE61 -Ethernet62 107 tenGigE62 -Ethernet63 108 tenGigE63 -Ethernet64 109 tenGigE64 -Ethernet65 110 tenGigE65 -Ethernet66 111 tenGigE66 -Ethernet67 112 tenGigE67 -Ethernet68 77 tenGigE68 -Ethernet69 78 tenGigE69 -Ethernet70 79 tenGigE70 -Ethernet71 80 tenGigE71 - +# name lanes alias index +Ethernet0 13 tenGigE0 0 +Ethernet1 14 tenGigE1 1 +Ethernet2 15 tenGigE2 2 +Ethernet3 16 tenGigE3 3 +Ethernet4 21 tenGigE4 4 +Ethernet5 22 tenGigE5 5 +Ethernet6 23 tenGigE6 6 +Ethernet7 24 tenGigE7 7 +Ethernet8 25 tenGigE8 8 +Ethernet9 26 tenGigE9 9 +Ethernet10 27 tenGigE10 10 +Ethernet11 28 tenGigE11 11 +Ethernet12 29 tenGigE12 12 +Ethernet13 30 tenGigE13 13 +Ethernet14 31 tenGigE14 14 +Ethernet15 32 tenGigE15 15 +Ethernet16 45 tenGigE16 16 +Ethernet17 46 tenGigE17 17 +Ethernet18 47 tenGigE18 18 +Ethernet19 48 tenGigE19 19 +Ethernet20 49 tenGigE20 20 +Ethernet21 50 tenGigE21 21 +Ethernet22 51 tenGigE22 22 +Ethernet23 52 tenGigE23 23 +Ethernet24 53 tenGigE24 24 +Ethernet25 54 tenGigE25 25 +Ethernet26 55 tenGigE26 26 +Ethernet27 56 tenGigE27 27 +Ethernet28 57 tenGigE28 28 +Ethernet29 58 tenGigE29 29 +Ethernet30 59 tenGigE30 30 +Ethernet31 60 tenGigE31 31 +Ethernet32 61 tenGigE32 32 +Ethernet33 62 tenGigE33 33 +Ethernet34 63 tenGigE34 34 +Ethernet35 64 tenGigE35 35 +Ethernet36 65 tenGigE36 36 +Ethernet37 66 tenGigE37 37 +Ethernet38 67 tenGigE38 38 +Ethernet39 68 tenGigE39 39 +Ethernet40 69 tenGigE40 40 +Ethernet41 70 tenGigE41 41 +Ethernet42 71 tenGigE42 42 +Ethernet43 72 tenGigE43 43 +Ethernet44 73 tenGigE44 44 +Ethernet45 74 tenGigE45 45 +Ethernet46 75 tenGigE46 46 +Ethernet47 76 tenGigE47 47 +Ethernet48 97 tenGigE48 48 +Ethernet49 98 tenGigE49 49 +Ethernet50 99 tenGigE50 50 +Ethernet51 100 tenGigE51 51 +Ethernet52 101 tenGigE52 52 +Ethernet53 102 tenGigE53 53 +Ethernet54 103 tenGigE54 54 +Ethernet55 104 tenGigE55 55 +Ethernet56 81 tenGigE56 56 +Ethernet57 82 tenGigE57 57 +Ethernet58 83 tenGigE58 58 +Ethernet59 84 tenGigE59 59 +Ethernet60 105 tenGigE60 60 +Ethernet61 106 tenGigE61 61 +Ethernet62 107 tenGigE62 62 +Ethernet63 108 tenGigE63 63 +Ethernet64 109 tenGigE64 64 +Ethernet65 110 tenGigE65 65 +Ethernet66 111 tenGigE66 66 +Ethernet67 112 tenGigE67 67 +Ethernet68 77 tenGigE68 68 +Ethernet69 78 tenGigE69 69 +Ethernet70 79 tenGigE70 70 +Ethernet71 80 tenGigE71 71 diff --git a/device/accton/x86_64-accton_as5712_54x-r0/Accton-AS5712-54X/sai.profile b/device/accton/x86_64-accton_as5712_54x-r0/Accton-AS5712-54X/sai.profile old mode 100644 new mode 100755 index 7fafa54db963..01d0f6642549 --- a/device/accton/x86_64-accton_as5712_54x-r0/Accton-AS5712-54X/sai.profile +++ b/device/accton/x86_64-accton_as5712_54x-r0/Accton-AS5712-54X/sai.profile @@ -1,2 +1 @@ SAI_INIT_CONFIG_FILE=/etc/bcm/td2-as5712-72x10G.config.bcm - diff --git a/device/accton/x86_64-accton_as5712_54x-r0/minigraph.xml b/device/accton/x86_64-accton_as5712_54x-r0/minigraph.xml old mode 100644 new mode 100755 index 8d89f28b0d86..78c3876d8381 --- a/device/accton/x86_64-accton_as5712_54x-r0/minigraph.xml +++ b/device/accton/x86_64-accton_as5712_54x-r0/minigraph.xml @@ -1,52 +1,622 @@ - + - OCPSCH0104001MS - 10.10.1.26 + ARISTA01T0 + 10.0.0.33 switch1 - 10.10.1.25 + 10.0.0.32 1 - 10 - 3 + 180 + 60 - OCPSCH0104002MS - 10.10.2.26 + switch1 + 10.0.0.0 + ARISTA01T2 + 10.0.0.1 + 1 + 180 + 60 + + + ARISTA02T0 + 10.0.0.35 + switch1 + 10.0.0.34 + 1 + 180 + 60 + + + switch1 + 10.0.0.2 + ARISTA02T2 + 10.0.0.3 + 1 + 180 + 60 + + + ARISTA03T0 + 10.0.0.37 + switch1 + 10.0.0.36 + 1 + 180 + 60 + + + switch1 + 10.0.0.4 + ARISTA03T2 + 10.0.0.5 + 1 + 180 + 60 + + + ARISTA04T0 + 10.0.0.39 + switch1 + 10.0.0.38 + 1 + 180 + 60 + + + switch1 + 10.0.0.6 + ARISTA04T2 + 10.0.0.7 + 1 + 180 + 60 + + + ARISTA05T0 + 10.0.0.41 + switch1 + 10.0.0.40 + 1 + 180 + 60 + + + switch1 + 10.0.0.8 + ARISTA05T2 + 10.0.0.9 + 1 + 180 + 60 + + + ARISTA06T0 + 10.0.0.43 + switch1 + 10.0.0.42 + 1 + 180 + 60 + + + switch1 + 10.0.0.10 + ARISTA06T2 + 10.0.0.11 + 1 + 180 + 60 + + + ARISTA07T0 + 10.0.0.45 + switch1 + 10.0.0.44 + 1 + 180 + 60 + + + switch1 + 10.0.0.12 + ARISTA07T2 + 10.0.0.13 + 1 + 180 + 60 + + + ARISTA08T0 + 10.0.0.47 + switch1 + 10.0.0.46 + 1 + 180 + 60 + + + switch1 + 10.0.0.14 + ARISTA08T2 + 10.0.0.15 + 1 + 180 + 60 + + + ARISTA09T0 + 10.0.0.49 + switch1 + 10.0.0.48 + 1 + 180 + 60 + + + switch1 + 10.0.0.16 + ARISTA09T2 + 10.0.0.17 + 1 + 180 + 60 + + + ARISTA10T0 + 10.0.0.51 + switch1 + 10.0.0.50 + 1 + 180 + 60 + + + switch1 + 10.0.0.18 + ARISTA10T2 + 10.0.0.19 + 1 + 180 + 60 + + + ARISTA11T0 + 10.0.0.53 + switch1 + 10.0.0.52 + 1 + 180 + 60 + + + switch1 + 10.0.0.20 + ARISTA11T2 + 10.0.0.21 + 1 + 180 + 60 + + + ARISTA12T0 + 10.0.0.55 + switch1 + 10.0.0.54 + 1 + 180 + 60 + + + switch1 + 10.0.0.22 + ARISTA12T2 + 10.0.0.23 + 1 + 180 + 60 + + + ARISTA13T0 + 10.0.0.57 + switch1 + 10.0.0.56 + 1 + 180 + 60 + + + switch1 + 10.0.0.24 + ARISTA13T2 + 10.0.0.25 + 1 + 180 + 60 + + + ARISTA14T0 + 10.0.0.59 + switch1 + 10.0.0.58 + 1 + 180 + 60 + + + switch1 + 10.0.0.26 + ARISTA14T2 + 10.0.0.27 + 1 + 180 + 60 + + + ARISTA15T0 + 10.0.0.61 + switch1 + 10.0.0.60 + 1 + 180 + 60 + + + switch1 + 10.0.0.28 + ARISTA15T2 + 10.0.0.29 + 1 + 180 + 60 + + + ARISTA16T0 + 10.0.0.63 switch1 - 10.10.2.25 + 10.0.0.62 1 - 10 - 3 + 180 + 60 + + + switch1 + 10.0.0.30 + ARISTA16T2 + 10.0.0.31 + 1 + 180 + 60 - 64536 - switch1 - - -
10.10.1.26
- - -
- -
10.10.2.26
- - -
-
+ 65100 + switch1 + + +
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 - 64542 - OCPSCH0104001MS + 65200 + ARISTA12T2 - 64543 - OCPSCH0104002MS + 64013 + ARISTA13T0 + + + + 65200 + ARISTA13T2 + + + + 64014 + ARISTA14T0 + + + + 65200 + ARISTA14T2 + + + + 64015 + ARISTA15T0 + + + + 65200 + ARISTA15T2 + + + + 64016 + ARISTA16T0 + + + + 65200 + ARISTA16T2
@@ -58,10 +628,10 @@ HostIP Loopback0 - - 100.0.0.9/32 + + 10.1.0.32/32 - 100.0.0.9/32 + 10.1.0.32/32 @@ -74,14 +644,364 @@ - - Ethernet48 - 10.10.1.25/30 + + tenGigE0 + 10.0.0.0/31 + + + + tenGigE1 + 10.0.0.2/31 + + + + tenGigE2 + 10.0.0.4/31 + + + + tenGigE3 + 10.0.0.6/31 + + + + tenGigE4 + 10.0.0.8/31 + + + + tenGigE5 + 10.0.0.10/31 + + + + tenGigE6 + 10.0.0.12/31 + + + + tenGigE7 + 10.0.0.14/31 + + + + tenGigE8 + 10.0.0.16/31 + + + + tenGigE9 + 10.0.0.18/31 + + + + tenGigE10 + 10.0.0.20/31 + + + + tenGigE11 + 10.0.0.22/31 + + + + tenGigE12 + 10.0.0.24/31 + + + + tenGigE13 + 10.0.0.26/31 + + + + tenGigE14 + 10.0.0.28/31 + + + + tenGigE15 + 10.0.0.30/31 + + + + tenGigE16 + 10.0.0.32/31 + + + + tenGigE17 + 10.0.0.34/31 + + + + tenGigE18 + 10.0.0.36/31 + + + + tenGigE19 + 10.0.0.38/31 + + + + tenGigE20 + 10.0.0.40/31 + + + + tenGigE21 + 10.0.0.42/31 + + + + tenGigE22 + 10.0.0.44/31 + + + + tenGigE23 + 10.0.0.46/31 + + + + tenGigE24 + 10.0.0.48/31 + + + + tenGigE25 + 10.0.0.50/31 + + + + tenGigE26 + 10.0.0.52/31 + + + + tenGigE27 + 10.0.0.54/31 + + + + tenGigE28 + 10.0.0.56/31 + + + + tenGigE29 + 10.0.0.58/31 + + + + tenGigE30 + 10.0.0.60/31 + + + + tenGigE31 + 10.0.0.62/31 + + + + tenGigE32 + 10.0.0.64/31 + + + + tenGigE33 + 10.0.0.66/31 + + + + tenGigE34 + 10.0.0.68/31 + + + + tenGigE35 + 10.0.0.70/31 + + + + tenGigE36 + 10.0.0.72/31 + + + + tenGigE37 + 10.0.0.74/31 + + + + tenGigE38 + 10.0.0.76/31 + + + + tenGigE39 + 10.0.0.78/31 + + + + tenGigE40 + 10.0.0.80/31 + + + + tenGigE41 + 10.0.0.82/31 + + + + tenGigE42 + 10.0.0.84/31 + + + + tenGigE43 + 10.0.0.86/31 + + + + tenGigE44 + 10.0.0.88/31 + + + + tenGigE45 + 10.0.0.90/31 + + + + tenGigE46 + 10.0.0.92/31 + + + + tenGigE47 + 10.0.0.94/31 + + + + tenGigE48 + 10.0.0.96/31 + + + + tenGigE49 + 10.0.0.98/31 + + + + tenGigE50 + 10.0.0.100/31 + + + + tenGigE51 + 10.0.0.102/31 + + + + tenGigE52 + 10.0.0.104/31 + + + + tenGigE53 + 10.0.0.106/31 + + + + tenGigE54 + 10.0.0.108/31 + + + + tenGigE55 + 10.0.0.110/31 + + + + tenGigE56 + 10.0.0.112/31 + + + + tenGigE57 + 10.0.0.114/31 + + + + tenGigE58 + 10.0.0.116/31 + + + + tenGigE59 + 10.0.0.118/31 + + + + tenGigE60 + 10.0.0.120/31 + + + + tenGigE61 + 10.0.0.122/31 + + + + tenGigE62 + 10.0.0.124/31 + + + + tenGigE63 + 10.0.0.126/31 + + + + tenGigE64 + 10.0.0.128/31 + + + + tenGigE65 + 10.0.0.130/31 + + + + tenGigE66 + 10.0.0.132/31 + + + + tenGigE67 + 10.0.0.134/31 + + + + tenGigE68 + 10.0.0.136/31 + + + + tenGigE69 + 10.0.0.138/31 + + + + tenGigE70 + 10.0.0.140/31 - - Ethernet52 - 10.10.2.25/30 + + tenGigE71 + 10.0.0.142/31 @@ -92,21 +1012,229 @@ - - 40000 + + DeviceInterfaceLink + switch1 + tenGigE0 + ARISTA01T2 + tenGigE1 + + + DeviceInterfaceLink + switch1 + tenGigE1 + ARISTA02T2 + tenGigE1 + + + DeviceInterfaceLink + switch1 + tenGigE2 + ARISTA03T2 + tenGigE1 + + + DeviceInterfaceLink + switch1 + tenGigE3 + ARISTA04T2 + tenGigE1 + + + DeviceInterfaceLink + switch1 + tenGigE4 + ARISTA05T2 + tenGigE1 + + + DeviceInterfaceLink + switch1 + tenGigE5 + ARISTA06T2 + tenGigE1 + + + DeviceInterfaceLink + switch1 + tenGigE6 + ARISTA07T2 + tenGigE1 + + + DeviceInterfaceLink + switch1 + tenGigE7 + ARISTA08T2 + tenGigE1 + + + DeviceInterfaceLink + switch1 + tenGigE8 + ARISTA09T2 + tenGigE1 + + + DeviceInterfaceLink + switch1 + tenGigE9 + ARISTA10T2 + tenGigE1 + + + DeviceInterfaceLink + switch1 + tenGigE10 + ARISTA11T2 + tenGigE1 + + + DeviceInterfaceLink + switch1 + tenGigE11 + ARISTA12T2 + tenGigE1 + + + DeviceInterfaceLink + switch1 + tenGigE12 + ARISTA13T2 + tenGigE1 + + + DeviceInterfaceLink + switch1 + tenGigE13 + ARISTA14T2 + tenGigE1 + + + DeviceInterfaceLink + switch1 + tenGigE14 + ARISTA15T2 + tenGigE1 + + + DeviceInterfaceLink + switch1 + tenGigE15 + ARISTA16T2 + tenGigE1 + + + DeviceInterfaceLink + switch1 + tenGigE16 + ARISTA01T0 + tenGigE1 + + + DeviceInterfaceLink + switch1 + tenGigE17 + ARISTA02T0 + tenGigE1 + + + DeviceInterfaceLink + switch1 + tenGigE18 + ARISTA03T0 + tenGigE1 + + + DeviceInterfaceLink + switch1 + tenGigE19 + ARISTA04T0 + tenGigE1 + + + DeviceInterfaceLink + switch1 + tenGigE20 + ARISTA05T0 + tenGigE1 + + + DeviceInterfaceLink + switch1 + tenGigE21 + ARISTA06T0 + tenGigE1 + + + DeviceInterfaceLink + switch1 + tenGigE22 + ARISTA07T0 + tenGigE1 + + + DeviceInterfaceLink + switch1 + tenGigE23 + ARISTA08T0 + tenGigE1 + + + DeviceInterfaceLink + switch1 + tenGigE24 + ARISTA09T0 + tenGigE1 + + + DeviceInterfaceLink + switch1 + tenGigE25 + ARISTA10T0 + tenGigE1 + + + DeviceInterfaceLink + switch1 + tenGigE26 + ARISTA11T0 + tenGigE1 + + + DeviceInterfaceLink + switch1 + tenGigE27 + ARISTA12T0 + tenGigE1 + + + DeviceInterfaceLink + switch1 + tenGigE28 + ARISTA13T0 + tenGigE1 + + + DeviceInterfaceLink + switch1 + tenGigE29 + ARISTA14T0 + tenGigE1 + + DeviceInterfaceLink - OCPSCH0104001MS - Ethernet24 - switch1 - Ethernet48 + switch1 + tenGigE30 + ARISTA15T0 + tenGigE1 - - 40000 + DeviceInterfaceLink - OCPSCH0104002MS - Ethernet24 - switch1 - Ethernet52 + switch1 + tenGigE31 + ARISTA16T0 + tenGigE1 @@ -115,7 +1243,7 @@ Accton-AS5712-54X - + @@ -136,11 +1264,6 @@ - - ErspanDestinationIpv4 - - 2.2.2.2 - diff --git a/device/accton/x86_64-accton_as5712_54x-r0/plugins/sfputil.py b/device/accton/x86_64-accton_as5712_54x-r0/plugins/sfputil.py old mode 100644 new mode 100755 index 070b1da934cb..c9862957bf31 --- a/device/accton/x86_64-accton_as5712_54x-r0/plugins/sfputil.py +++ b/device/accton/x86_64-accton_as5712_54x-r0/plugins/sfputil.py @@ -14,12 +14,90 @@ class SfpUtil(SfpUtilBase): """Platform-specific SfpUtil class""" PORT_START = 0 - PORT_END = 31 - PORTS_IN_BLOCK = 32 + PORT_END = 71 + PORTS_IN_BLOCK = 72 + QSFP_PORT_START = 72 + QSFP_PORT_END = 72 - EEPROM_OFFSET = 20 + BASE_VAL_PATH = "/sys/class/i2c-adapter/i2c-{0}/{1}-0050/" + + _port_to_is_present = {} _port_to_eeprom_mapping = {} + _port_to_i2c_mapping = { + 0: [2, 2], + 1: [3, 3], + 2: [4, 4], + 3: [5, 5], + 4: [6, 6], + 5: [7, 7], + 6: [8, 8], + 7: [9, 9], + 8: [10, 10], + 9: [11, 11], + 10: [12, 12], + 11: [13, 13], + 12: [14, 14], + 13: [15, 15], + 14: [16, 16], + 15: [17, 17], + 16: [18, 18], + 17: [19, 19], + 18: [20, 20], + 19: [21, 21], + 20: [22, 22], + 21: [23, 23], + 22: [24, 24], + 23: [25, 25], + 24: [26, 26], + 25: [27, 27], + 26: [28, 28], + 27: [29, 29], + 28: [30, 30], + 29: [31, 31], + 30: [32, 32], + 31: [33, 33], + 32: [34, 34], + 33: [35, 35], + 34: [36, 36], + 35: [37, 37], + 36: [38, 38], + 37: [39, 39], + 38: [40, 40], + 39: [41, 41], + 40: [42, 42], + 41: [43, 43], + 42: [44, 44], + 43: [45, 45], + 44: [46, 46], + 45: [47, 47], + 46: [48, 48], + 47: [49, 49], + 48: [50, 50], #QSFP49 + 49: [50, 50], + 50: [50, 50], + 51: [50, 50], + 52: [52, 52], #QSFP50 + 53: [52, 52], + 54: [52, 52], + 55: [52, 52], + 56: [54, 54], #QSFP51 + 57: [54, 54], + 58: [54, 54], + 59: [54, 54], + 60: [51, 51], #QSFP52 + 61: [51, 51], + 62: [51, 51], + 63: [51, 51], + 64: [53, 53], #QSFP53 + 65: [53, 53], + 66: [53, 53], + 67: [53, 53], + 68: [55, 55], #QSFP54 + 69: [55, 55], + 70: [55, 55], + 71: [55, 55], + } @property def port_start(self): @@ -31,17 +109,19 @@ def port_end(self): @property def qsfp_ports(self): - return range(0, self.PORTS_IN_BLOCK + 1) + return range(self.QSFP_PORT_START, self.PORTS_IN_BLOCK + 1) @property def port_to_eeprom_mapping(self): return self._port_to_eeprom_mapping def __init__(self): - eeprom_path = "/sys/class/i2c-adapter/i2c-{0}/{0}-0050/eeprom" + eeprom_path = self.BASE_VAL_PATH + "sfp_eeprom" - for x in range(0, self.port_end + 1): - self._port_to_eeprom_mapping[x] = eeprom_path.format(x + self.EEPROM_OFFSET) + for x in range(0, self.port_end+1): + self.port_to_eeprom_mapping[x] = eeprom_path.format( + self._port_to_i2c_mapping[x][0], + self._port_to_i2c_mapping[x][1]) SfpUtilBase.__init__(self) @@ -50,126 +130,29 @@ def get_presence(self, port_num): if port_num < self.port_start or port_num > self.port_end: return False + present_path = self.BASE_VAL_PATH + "sfp_is_present" + self.__port_to_is_present = present_path.format(self._port_to_i2c_mapping[port_num][0], self._port_to_i2c_mapping[port_num][1]) + try: - reg_file = open("/sys/devices/platform/accton/qsfp_modprs") + val_file = open(self.__port_to_is_present) except IOError as e: - print "Error: unable to open file: %s" % str(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) - - # Mask off the bit corresponding to our port - mask = (1 << port_num) + content = val_file.readline().rstrip() + val_file.close() - # ModPrsL is active low - if reg_value & mask == 0: + # content is a string, either "0" or "1" + if content == "1": 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 - - try: - reg_file = open("/sys/devices/platform/accton/qsfp_lpmode") - except IOError as e: - print "Error: unable to open file: %s" % str(e) - - content = reg_file.readline().rstrip() - - # content is a string containing the hex representation of the register - reg_value = int(content, 16) - - # Mask off the bit corresponding to our port - mask = (1 << port_num) - - # LPMode is active high - if reg_value & mask == 0: - return False - - return True + raise NotImplementedError def set_low_power_mode(self, port_num, lpmode): - # Check for invalid port_num - if port_num < self.port_start or port_num > self.port_end: - return False - - try: - reg_file = open("/sys/devices/platform/accton/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) - - # Mask off the bit corresponding to our port - mask = (1 << port_num) - - # 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) - - reg_file.seek(0) - reg_file.write(content) - reg_file.close() - - return True + raise NotImplementedError def reset(self, port_num): - QSFP_RESET_REGISTER_DEVICE_FILE = "/sys/devices/platform/accton/qsfp_reset" - - # Check for invalid port_num - if port_num < self.port_start or port_num > self.port_end: - return False - - try: - reg_file = open(QSFP_RESET_REGISTER_DEVICE_FILE, "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) - - # Mask off the bit corresponding to our port - mask = (1 << port_num) - - # 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)) - 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(QSFP_RESET_REGISTER_DEVICE_FILE, "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)) - reg_file.close() - - return True + raise NotImplementedError diff --git a/device/accton/x86_64-accton_as7712_32x-r0/plugins/sfputil.py b/device/accton/x86_64-accton_as7712_32x-r0/plugins/sfputil.py index 6dc35d72bb21..c13eecfd1759 100644 --- a/device/accton/x86_64-accton_as7712_32x-r0/plugins/sfputil.py +++ b/device/accton/x86_64-accton_as7712_32x-r0/plugins/sfputil.py @@ -1,19 +1,19 @@ #!/usr/bin/env python try: - from sonic_sfp.sfputilbase import sfputilbase + from sonic_sfp.sfputilbase import SfpUtilBase except ImportError, e: raise ImportError (str(e) + "- required module not found") -class sfputil(sfputilbase): - """Platform specific sfputil class""" +class SfpUtil(SfpUtilBase): + """Platform specific SfpUtill class""" - port_start = 0 - port_end = 31 + _port_start = 0 + _port_end = 31 ports_in_block = 32 - port_to_eeprom_mapping = {} + _port_to_eeprom_mapping = {} port_to_i2c_mapping = { 9 : 18, 10 : 19, @@ -51,10 +51,58 @@ class sfputil(sfputilbase): _qsfp_ports = range(0, ports_in_block + 1) - def __init__(self, port_num): - # Override port_to_eeprom_mapping for class initialization + def __init__(self): eeprom_path = '/sys/bus/i2c/devices/{0}-0050/sfp_eeprom' - for x in range(self.port_start, self.port_end + 1): + for x in range(0, self._port_end + 1): port_eeprom_path = eeprom_path.format(self.port_to_i2c_mapping[x+1]) - self.port_to_eeprom_mapping[x] = port_eeprom_path - sfputilbase.__init__(self, port_num) + self._port_to_eeprom_mapping[x] = port_eeprom_path + SfpUtilBase.__init__(self) + + def reset(self, port_num): + return True + def set_low_power_mode(self, port_nuM, lpmode): + return True + def get_low_power_mode(self, port_num): + return True + +# def get_presence(self, port_num): +# return True + + def get_presence(self, port_num): + # Check for invalid port_num + if port_num < self._port_start or port_num > self._port_end: + return False + + path = "/sys/bus/i2c/devices/{0}-0050/sfp_is_present" + port_ps = path.format(self.port_to_i2c_mapping[port_num+1]) + + + try: + reg_file = open(port_ps) + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + reg_value = reg_file.readline().rstrip() + if reg_value == '1': + return True + + return False + + @property + def port_start(self): + return self._port_start + + @property + def port_end(self): + return self._port_end + + @property + def qsfp_ports(self): + return range(0, self.ports_in_block + 1) + + @property + def port_to_eeprom_mapping(self): + return self._port_to_eeprom_mapping + + 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 new file mode 100644 index 000000000000..2539513d8e1f --- /dev/null +++ b/device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/qos.json @@ -0,0 +1,156 @@ +{ + "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" + } + }, + "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]", + "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]" + }, + "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/arista/x86_64-arista_7050_qx32/plugins/psuutil.py b/device/arista/x86_64-arista_7050_qx32/plugins/psuutil.py new file mode 100644 index 000000000000..1a8682ae3c67 --- /dev/null +++ b/device/arista/x86_64-arista_7050_qx32/plugins/psuutil.py @@ -0,0 +1,12 @@ +# psuutil.py +# +# Platform-specific PSU interface for SONiC +# + +try: + import arista.utils.sonic_psu as arista_psuutil +except ImportError as e: + raise ImportError("%s - required module not found" % str(e)) + + +PsuUtil = arista_psuutil.getPsuUtil() diff --git a/device/arista/x86_64-arista_7050_qx32/sensors.conf b/device/arista/x86_64-arista_7050_qx32/sensors.conf index dde0d35df8cb..469f63eaf1e4 100644 --- a/device/arista/x86_64-arista_7050_qx32/sensors.conf +++ b/device/arista/x86_64-arista_7050_qx32/sensors.conf @@ -12,38 +12,38 @@ chip "k10temp-pci-00c3" label temp1 "Cpu temp sensor" chip "lm73-i2c-3-48" - label temp1 "Rear Temp Sensor" + label temp1 "Back panel temp sensor" set temp1_max 65 #set temp1_max_alarm 75 # read-only chip "max6658-i2c-2-4c" - label temp1 "Board Temp Sensor" + label temp1 "Board temp sensor" set temp1_max 65 set temp1_crit 75 - label temp2 "Front-panel Temp Sensor" + label temp2 "Front panel temp sensor" set temp2_max 65 set temp2_crit 75 # disabled because of some eeprom corruption risks #chip "pmbus-i2c-3-4e" -# label temp1 "Power Controller Sensor 1" +# label temp1 "Power controller sensor 1" # set temp1_max 60 # set temp1_crit 70 -# label temp2 "Power Controller Sensor 2" +# label temp2 "Power controller sensor 2" # set temp2_max 60 # set temp2_crit 70 # ignore curr1 chip "dps460-i2c-5-58" - label temp1 "Power Supply 1 Sensor 1" + label temp1 "Power supply 1 inlet temp sensor" # maximum and critical thresholds are not supported for this psu set temp1_max 60 set temp1_crit 70 - label temp2 "Power Supply 1 Sensor 2" + label temp2 "Power supply 1 internal sensor" set temp2_max 60 set temp2_crit 70 @@ -60,12 +60,12 @@ chip "dps460-i2c-5-58" set curr2_crit 37 chip "dps460-i2c-6-58" - label temp1 "Power Supply 2 Sensor 1" + label temp1 "Power supply 2 inlet temp sensor" # maximum and critical thresholds are not supported for this psu set temp1_max 60 set temp1_crit 70 - label temp2 "Power Supply 2 Sensor 2" + label temp2 "Power supply 2 internal sensor" set temp2_max 60 set temp2_crit 70 diff --git a/device/arista/x86_64-arista_7050_qx32s/plugins/psuutil.py b/device/arista/x86_64-arista_7050_qx32s/plugins/psuutil.py new file mode 100644 index 000000000000..1a8682ae3c67 --- /dev/null +++ b/device/arista/x86_64-arista_7050_qx32s/plugins/psuutil.py @@ -0,0 +1,12 @@ +# psuutil.py +# +# Platform-specific PSU interface for SONiC +# + +try: + import arista.utils.sonic_psu as arista_psuutil +except ImportError as e: + raise ImportError("%s - required module not found" % str(e)) + + +PsuUtil = arista_psuutil.getPsuUtil() diff --git a/device/arista/x86_64-arista_7060_cx32s/plugins/psuutil.py b/device/arista/x86_64-arista_7060_cx32s/plugins/psuutil.py new file mode 100644 index 000000000000..1a8682ae3c67 --- /dev/null +++ b/device/arista/x86_64-arista_7060_cx32s/plugins/psuutil.py @@ -0,0 +1,12 @@ +# psuutil.py +# +# Platform-specific PSU interface for SONiC +# + +try: + import arista.utils.sonic_psu as arista_psuutil +except ImportError as e: + raise ImportError("%s - required module not found" % str(e)) + + +PsuUtil = arista_psuutil.getPsuUtil() diff --git a/device/arista/x86_64-arista_7060_cx32s/sensors.conf b/device/arista/x86_64-arista_7060_cx32s/sensors.conf index 20ebbeb5bbc7..21b21fcb5d1c 100644 --- a/device/arista/x86_64-arista_7060_cx32s/sensors.conf +++ b/device/arista/x86_64-arista_7060_cx32s/sensors.conf @@ -11,12 +11,25 @@ bus "i2c-7" "SCD SMBus master 0 bus 5" chip "k10temp-pci-00c3" label temp1 "Cpu temp sensor" -# missing support for -# chip "max6697-i2c-2-1a" -# board sensor 65 75 -# (1) switch chip left sensor 95 105 -# (5) switch chip right sensor 95 105 -# (6) front panel temp sensor 65 75 +chip "max6697-i2c-2-1a" + label temp1 "Board sensor" + set temp1_max 95 + + label temp2 "Switch chip left sensor" + set temp2_max 95 + set temp2_crit 105 + + ignore temp3 + ignore temp4 + ignore temp5 + + label temp6 "Switch chip right sensor" + set temp6_max 95 + set temp6_crit 105 + + label temp7 "Front panel temp sensor" + set temp7_max 65 + set temp7_crit 75 chip "max6658-i2c-3-4c" label temp1 "Cpu board temp sensor" @@ -38,9 +51,9 @@ chip "pmbus-i2c-7-4e" chip "pmbus-i2c-6-58" label temp1 "Power supply 1 hotspot sensor" label temp2 "Power supply 1 inlet temp sensor" - label temp3 "Power supply 1 sensor" + label temp3 "Power supply 1 exhaust temp sensor" chip "pmbus-i2c-5-58" label temp1 "Power supply 2 hotspot sensor" label temp2 "Power supply 2 inlet temp sensor" - label temp3 "Power supply 2 sensor" + label temp3 "Power supply 2 exhaust temp sensor" diff --git a/device/arista/x86_64-arista_7260cx3_64/plugins/psuutil.py b/device/arista/x86_64-arista_7260cx3_64/plugins/psuutil.py new file mode 100644 index 000000000000..1a8682ae3c67 --- /dev/null +++ b/device/arista/x86_64-arista_7260cx3_64/plugins/psuutil.py @@ -0,0 +1,12 @@ +# psuutil.py +# +# Platform-specific PSU interface for SONiC +# + +try: + import arista.utils.sonic_psu as arista_psuutil +except ImportError as e: + raise ImportError("%s - required module not found" % str(e)) + + +PsuUtil = arista_psuutil.getPsuUtil() diff --git a/device/arista/x86_64-arista_7260cx3_64/sensors.conf b/device/arista/x86_64-arista_7260cx3_64/sensors.conf index e0ad4b434972..1dc02fbaef98 100644 --- a/device/arista/x86_64-arista_7260cx3_64/sensors.conf +++ b/device/arista/x86_64-arista_7260cx3_64/sensors.conf @@ -8,7 +8,7 @@ bus "i2c-73" "SCD 0000:ff:0b.3 SMBus master 0 bus 0" bus "i2c-88" "SCD 0000:ff:0b.3 SMBus master 3 bus 3" chip "max6658-i2c-1-4c" - label temp1 "Temp sensor near TH2" + label temp1 "Asic temp sensor" set temp1_max 65 set temp1_crit 75 @@ -16,9 +16,9 @@ chip "max6658-i2c-1-4c" ignore temp2 chip "pmbus-i2c-3-58" - label temp1 "PSU1 primary hotspot temp" - label temp2 "PSU1 inlet temp" - label temp3 "PSU1 exhaust temp" + label temp1 "Power supply 1 hotspot sensor" + label temp2 "Power supply 1 inlet temp sensor" + label temp3 "Power supply 1 exhaust temp sensor" # setting maximum and critical thresholds is not supported for this psu # fault and warning limits defined internally by hardware @@ -27,9 +27,9 @@ chip "pmbus-i2c-3-58" ignore fan3 chip "pmbus-i2c-4-58" - label temp1 "PSU2 primary hotspot temp" - label temp2 "PSU2 inlet temp" - label temp3 "PSU2 exhaust temp" + label temp1 "Power supply 2 hotspot sensor" + label temp2 "Power supply 2 inlet temp sensor" + label temp3 "Power supply 2 exhaust temp sensor" # setting maximum and critical thresholds is not supported for this psu # fault and warning limits defined internally by hardware @@ -38,8 +38,8 @@ chip "pmbus-i2c-4-58" ignore fan3 chip "max6658-i2c-73-4c" - label temp1 "Rear air temp1" - label temp2 "Rear air temp2" + label temp1 "Back panel temp sensor 1" + label temp2 "Back panel temp sensor 2" set temp1_max 65 set temp1_crit 75 @@ -47,7 +47,7 @@ chip "max6658-i2c-73-4c" set temp2_crit 75 chip "lm73-i2c-88-48" - label temp1 "Front air temp" + label temp1 "Front panel temp sensor" set temp1_max 65 set temp1_crit 75 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 new file mode 100644 index 000000000000..2539513d8e1f --- /dev/null +++ b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000/qos.json @@ -0,0 +1,156 @@ +{ + "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" + } + }, + "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]", + "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]" + }, + "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/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/qos.json b/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/qos.json new file mode 100644 index 000000000000..32f337770c0f --- /dev/null +++ b/device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/qos.json @@ -0,0 +1,156 @@ +{ + "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" + } + }, + "PORT_QOS_MAP": { + "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": { + "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,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]" + }, + "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" : { + "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: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.2]" + } + } +} diff --git a/device/dell/x86_64-dell_s6100_c2538-r0/plugins/psuutil.py b/device/dell/x86_64-dell_s6100_c2538-r0/plugins/psuutil.py new file mode 100644 index 000000000000..5ae96a841908 --- /dev/null +++ b/device/dell/x86_64-dell_s6100_c2538-r0/plugins/psuutil.py @@ -0,0 +1,80 @@ +# +# psuutil.py +# Platform-specific PSU status interface for SONiC +# + + +import os.path + +try: + from sonic_psu.psu_base import PsuBase +except ImportError, e: + raise ImportError(str(e) + "- required module not found") + + +class PsuUtil(PsuBase): + """Platform-specific PSUutil class""" + + def __init__(self): + PsuBase.__init__(self) + + # Get a mailbox register + def get_pmc_register(self, reg_name): + mailbox_dir = "/sys/devices/platform/dell_s6100_lpc" + retval = 'ERR' + mb_reg_file = mailbox_dir+'/' + reg_name + if (not os.path.isfile(mb_reg_file)): + print mb_reg_file, 'not found !' + return retval + + try: + with open(mb_reg_file, 'r') as fd: + retval = fd.read() + except Exception as error: + logging.error("Unable to open ", mb_reg_file, "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 + """ + S6100_MAX_PSUS = 2 + return S6100_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 + psu_status = self.get_pmc_register('psu_'+str(index)+'_status') + if (psu_status != 'ERR'): + psu_status = int(psu_status, 16) + # Check for PSU statuse + if (~psu_status & 0b1000) or (psu_status & 0b0100): + 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_presence = self.get_pmc_register('psu_'+str(index)+'_status') + if (psu_presence != 'ERR'): + psu_presence = int(psu_presence, 16) + # Check for PSU presence + if (~psu_presence & 0b1): + status = 1 + + return status diff --git a/device/dell/x86_64-dell_z9100_c2538-r0/plugins/psuutil.py b/device/dell/x86_64-dell_z9100_c2538-r0/plugins/psuutil.py new file mode 100644 index 000000000000..d3d4f9d2b34c --- /dev/null +++ b/device/dell/x86_64-dell_z9100_c2538-r0/plugins/psuutil.py @@ -0,0 +1,80 @@ +# +# psuutil.py +# Platform-specific PSU status interface for SONiC +# + + +import os.path + +try: + from sonic_psu.psu_base import PsuBase +except ImportError, e: + raise ImportError(str(e) + "- required module not found") + + +class PsuUtil(PsuBase): + """Platform-specific PSUutil class""" + + def __init__(self): + PsuBase.__init__(self) + + # Get a mailbox register + def get_pmc_register(self, reg_name): + mailbox_dir = "/sys/devices/platform/dell_mailbox" + retval = 'ERR' + mb_reg_file = mailbox_dir+'/' + reg_name + if (not os.path.isfile(mb_reg_file)): + print mb_reg_file, 'not found !' + return retval + + try: + with open(mb_reg_file, 'r') as fd: + retval = fd.read() + except Exception as error: + logging.error("Unable to open ", mb_reg_file, "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 + """ + Z9100_MAX_PSUS = 2 + return Z9100_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 + psu_status = self.get_pmc_register('psu_'+str(index)+'_status') + if (psu_status != 'ERR'): + psu_status = int(psu_status, 16) + # Check for PSU statuse + if (~psu_status & 0b1000) or (psu_status & 0b0100): + 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_presence = self.get_pmc_register('psu_'+str(index)+'_status') + if (psu_presence != 'ERR'): + psu_presence = int(psu_presence, 16) + # Check for PSU presence + if (~psu_presence & 0b1): + status = 1 + + return status diff --git a/device/delta/x86_64-delta_ag9032v1-r0/Delta-ag9032v1/port_config.ini b/device/delta/x86_64-delta_ag9032v1-r0/Delta-ag9032v1/port_config.ini new file mode 100644 index 000000000000..e000f29bef38 --- /dev/null +++ b/device/delta/x86_64-delta_ag9032v1-r0/Delta-ag9032v1/port_config.ini @@ -0,0 +1,33 @@ +# name lanes alias +Ethernet0 49,50,51,52 hundredGigE1/1 +Ethernet4 53,54,55,56 hundredGigE1/2 +Ethernet8 57,58,59,60 hundredGigE1/3 +Ethernet12 61,62,63,64 hundredGigE1/4 +Ethernet16 65,66,67,68 hundredGigE1/5 +Ethernet20 69,70,71,72 hundredGigE1/6 +Ethernet24 73,74,75,76 hundredGigE1/7 +Ethernet28 77,78,79,80 hundredGigE1/8 +Ethernet32 37,38,39,40 hundredGigE1/9 +Ethernet36 33,34,35,36 hundredGigE1/10 +Ethernet40 45,46,47,48 hundredGigE1/11 +Ethernet44 41,42,43,44 hundredGigE1/12 +Ethernet48 81,82,83,84 hundredGigE1/13 +Ethernet52 85,86,87,88 hundredGigE1/14 +Ethernet56 89,90,91,92 hundredGigE1/15 +Ethernet60 93,94,95,96 hundredGigE1/16 +Ethernet64 97,98,99,100 hundredGigE1/17 +Ethernet68 101,102,103,104 hundredGigE1/18 +Ethernet72 105,106,107,108 hundredGigE1/19 +Ethernet76 109,110,111,112 hundredGigE1/20 +Ethernet80 21,22,23,24 hundredGigE1/21 +Ethernet84 17,18,19,20 hundredGigE1/22 +Ethernet88 29,30,31,32 hundredGigE1/23 +Ethernet92 25,26,27,28 hundredGigE1/24 +Ethernet96 117,118,119,120 hundredGigE1/25 +Ethernet100 113,114,115,116 hundredGigE1/26 +Ethernet104 125,126,127,128 hundredGigE1/27 +Ethernet108 121,122,123,124 hundredGigE1/28 +Ethernet112 5,6,7,8 hundredGigE1/29 +Ethernet116 1,2,3,4 hundredGigE1/30 +Ethernet120 13,14,15,16 hundredGigE1/31 +Ethernet124 9,10,11,12 hundredGigE1/32 diff --git a/device/delta/x86_64-delta_ag9032v1-r0/Delta-ag9032v1/sai.profile b/device/delta/x86_64-delta_ag9032v1-r0/Delta-ag9032v1/sai.profile new file mode 100644 index 000000000000..08d9e7fa3b47 --- /dev/null +++ b/device/delta/x86_64-delta_ag9032v1-r0/Delta-ag9032v1/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/etc/bcm/th-ag9032v1-32x100G.config.bcm diff --git a/device/delta/x86_64-delta_ag9032v1-r0/fancontrol b/device/delta/x86_64-delta_ag9032v1-r0/fancontrol new file mode 100644 index 000000000000..4a1cde92478f --- /dev/null +++ b/device/delta/x86_64-delta_ag9032v1-r0/fancontrol @@ -0,0 +1,10 @@ +INTERVAL=10 +DEVPATH=hwmon1=/sys/bus/i2c/devices +DEVNAME=hwmon1=emc2305 +FCTEMPS=hwmon1/2-004d/hwmon/hwmon*/temp1_input hwmon1/7-004c/hwmon/hwmon*/temp1_input hwmon1/7-004d/hwmon/hwmon*/temp1_input hwmon1/7-004e/hwmon/hwmon*/temp1_input hwmon1/30-004f/hwmon/hwmon*/temp1_input hwmon1/40-0058/temp1_input hwmon1/41-0058/temp1_input + +FCFANS=hwmon1/37-002c/fan1_input hwmon1/37-002c/fan2_input hwmon1/37-002c/fan3_input hwmon1/37-002c/fan4_input hwmon1/37-002c/fan5_input hwmon1/38-002d/fan1_input hwmon1/38-002d/fan2_input hwmon1/38-002d/fan3_input hwmon1/38-002d/fan4_input hwmon1/38-002d/fan5_input +MINTEMP=20 +MAXTEMP=60 +MINSTART=75 +MINSTOP=22 diff --git a/device/delta/x86_64-delta_ag9032v1-r0/fancontrol.service b/device/delta/x86_64-delta_ag9032v1-r0/fancontrol.service new file mode 100755 index 000000000000..17f647effb5b --- /dev/null +++ b/device/delta/x86_64-delta_ag9032v1-r0/fancontrol.service @@ -0,0 +1,244 @@ +#!/bin/bash +# +# Simple script implementing a temperature dependent fan speed control +# Supported Linux kernel versions: 2.6.5 and later +# +# Version 0.70 +# +# Usage: fancontrol [CONFIGFILE] +# +# Dependencies: +# bash, egrep, sed, cut, sleep, readlink, lm_sensors :) +# +# Please send any questions, comments or success stories to +# marius.reiner@hdev.de +# Thanks! +# +# For configuration instructions and warnings please see fancontrol.txt, which +# can be found in the doc/ directory or at the website mentioned above. +# +# +# Copyright 2003 Marius Reiner +# Copyright (C) 2007-2009 Jean Delvare +# +# 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. +# +# + +PIDFILE="/var/run/fancontrol.pid" + +#DEBUG=1 +MAX=255 + +function LoadConfig +{ + local fcvcount fcv + + echo "Loading configuration from $1 ..." + if [ ! -r "$1" ] + then + echo "Error: Can't read configuration file" >&2 + exit 1 + fi + + # grep configuration from file + INTERVAL=`egrep '^INTERVAL=.*$' $1 | sed -e 's/INTERVAL=//g'` + DEVPATH=`egrep '^DEVPATH=.*$' $1 | sed -e 's/DEVPATH= *//g'` + DEVNAME=`egrep '^DEVNAME=.*$' $1 | sed -e 's/DEVNAME= *//g'` + FCTEMPS=`egrep '^FCTEMPS=.*$' $1 | sed -e 's/FCTEMPS=//g'` + MINTEMP=`egrep '^MINTEMP=.*$' $1 | sed -e 's/MINTEMP=//g'` + MAXTEMP=`egrep '^MAXTEMP=.*$' $1 | sed -e 's/MAXTEMP=//g'` + MINSTART=`egrep '^MINSTART=.*$' $1 | sed -e 's/MINSTART=//g'` + MINSTOP=`egrep '^MINSTOP=.*$' $1 | sed -e 's/MINSTOP=//g'` + HWMON=$( echo "$DEVPATH" | sed 's/=.*$//g') + FCDEVPATH=$( echo "$DEVPATH" | sed 's/^.*=//g') + FCMINTEMP=$MINTEMP + FCMAXTEMP=$MAXTEMP + FCMINSTART=$MINSTART + FCMINSTOP=$MINSTOP + + FCFANS=`egrep '^FCFANS=.*$' $1 | sed -e 's/FCFANS=//g'` + + # Check whether all mandatory settings are set + if [[ -z ${INTERVAL} || -z ${FCTEMPS} || -z ${MINTEMP} || -z ${MAXTEMP} || -z ${MINSTART} || -z ${MINSTOP} ]] + then + echo "Some mandatory settings missing, please check your config file!" >&2 + exit 1 + fi + if [ "$INTERVAL" -le 0 ] + then + echo "Error in configuration file:" >&2 + echo "INTERVAL must be at least 1" >&2 + exit 1 + fi + + # write settings to arrays for easier use and print them + echo + echo "Common settings:" + + temp_string=$FCTEMPS + + let fcvcount=0 + for fcv in $FCTEMPS + do + fcvcount=$((fcvcount+1)) + AFCTEMP[$fcvcount]=$( echo "$temp_string" | cut -d" " -f $fcvcount ) + AFCTEMP[$fcvcount]=$( echo "${AFCTEMP[$fcvcount]}" | sed 's/hwmon1/\/sys\/bus\/i2c\/devices/g' ) + AFCTEMP_PATH[$fcvcount]=$( echo "${AFCTEMP[$fcvcount]}" | sed 's/hwmon1/\/sys\/bus\/i2c\/devices/g' ) + + AFCTEMP[$fcvcount]=$( cat ${AFCTEMP[$fcvcount]} ) + AFCTEMP[$fcvcount]=$(( AFCTEMP[$fcvcount]/1000 )) + done + + fan_string=$FCFANS + fcvcount=0 + zero=0 + for fcv in $FCFANS + do + fcvcount=$((fcvcount+1)) + AFCFAN[$fcvcount]=$( echo "$fan_string" | cut -d" " -f $fcvcount ) + AFCFAN_PATH[$fcvcount]=$( echo "${AFCFAN[$fcvcount]}" | sed 's/hwmon1/\/sys\/bus\/i2c\/devices/g' ) + AFCFAN_TARGET[$fcvcount]=$( echo "${AFCFAN_PATH[$fcvcount]}" | sed 's/hwmon1/\/sys\/bus\/i2c\/devices/g' ) + AFCFAN_TARGET[$fcvcount]=$( echo "${AFCFAN_TARGET[$fcvcount]}" | sed 's/$/_percentage/g') + AFCFAN[$fcvcount]=$( cat ${AFCFAN_PATH[$fcvcount]} ) + if [ "${AFCFAN[$fcvcount]}" == 960 ] + then + AFCFAN[$fcvcount]=$zero + fi + done +} + +# Check that all referenced sysfs files exist +function CheckFiles +{ + local outdated=0 fcvcount tsen fan + if [ $outdated -eq 1 ] + then + echo >&2 + echo "At least one referenced file is missing. Either some required kernel" >&2 + echo "modules haven't been loaded, or your configuration file is outdated." >&2 + echo "In the latter case, you should run pwmconfig again." >&2 + fi + return $outdated +} + +LoadConfig $1 + +# Detect path to sensors +if [ ! -d $DIR ] +then + echo $0: 'No sensors found! (did you load the necessary modules?)' >&2 + exit 1 +fi +cd $DIR + +# Check for configuration change +if [ "$DIR" != "/" ] && [ -z "$DEVPATH" -o -z "$DEVNAME" ] +then + echo "Configuration is too old, please run pwmconfig again" >&2 + exit 1 +fi +if [ "$DIR" = "/" -a -n "$DEVPATH" ] +then + echo "Unneeded DEVPATH with absolute device paths" >&2 + exit 1 +fi +CheckFiles || exit 1 + +if [ -f "$PIDFILE" ] +then + echo "File $PIDFILE exists, is fancontrol already running?" >&2 + exit 1 +fi +echo $$ > "$PIDFILE" + + +# main function +function UpdateThermalSensors +{ + echo "" + TEMP_HIGHEST=0 + FAN_PERCENTAGE=0 + + for i in ${AFCTEMP_PATH[@]}; do + if (( $(cat $i) > $TEMP_HIGHEST )); then + TEMP_HIGHEST=$(cat $i); + fi; + done + TEMP_HIGHEST=$((TEMP_HIGHEST/1000)) + echo "The highest temperature of thermal sensors: $TEMP_HIGHEST °C" +} + +function UpdateFanSpeeds +{ + if [ $TEMP_HIGHEST -lt 51 ]; then #TEMP<=50 + FAN_PERCENTAGE=40 + elif [ $TEMP_HIGHEST -lt 56 -a $TEMP_HIGHEST -gt 50 ]; then #50 ${AFCFAN_TARGET[$fcvcount]} + AFCFAN[$fcvcount]=$( cat ${AFCFAN_PATH[$fcvcount]} ) + + if [ "${AFCFAN[$fcvcount]}" == 960 ] + then + AFCFAN[$fcvcount]=$zero + fi + done + + if [ $TEMP_HIGHEST -lt 51 ]; then #TEMP<=50 + FAN_ON_PSU_PERCENTAGE=50 + elif [ $TEMP_HIGHEST -lt 100 -a $TEMP_HIGHEST -gt 50 ]; then #50 '/sys/bus/i2c/devices/4-0058/psu_select_member' + echo "$FAN_ON_PSU_PERCENTAGE" > '/sys/bus/i2c/devices/40-0058/fan1_set_percentage' + echo "PSU fan1 =$( cat '/sys/bus/i2c/devices/40-0058/fan1_input' ) (rpm)" + #Set speed to PSU_FAN2 + #echo "0x20" > '/sys/bus/i2c/devices/4-0058/psu_select_member' + echo "$FAN_ON_PSU_PERCENTAGE" > '/sys/bus/i2c/devices/41-0058/fan1_set_percentage' + echo "PSU fan2 =$( cat '/sys/bus/i2c/devices/41-0058/fan1_input' ) (rpm)" + + rm -f "$PIDFILE" +} +# main loop calling the main function at specified intervals +while true +do + UpdateThermalSensors + UpdateFanSpeeds + echo "Sleep $INTERVAL seconds ..." + # Sleep while still handling signals + sleep $INTERVAL & + wait $! +done diff --git a/device/delta/x86_64-delta_ag9032v1-r0/installer.conf b/device/delta/x86_64-delta_ag9032v1-r0/installer.conf new file mode 100644 index 000000000000..fa2af8b7a007 --- /dev/null +++ b/device/delta/x86_64-delta_ag9032v1-r0/installer.conf @@ -0,0 +1,2 @@ +CONSOLE_PORT=0x3f8 +CONSOLE_SPEED=115200 diff --git a/device/delta/x86_64-delta_ag9032v1-r0/led_proc_init.soc b/device/delta/x86_64-delta_ag9032v1-r0/led_proc_init.soc new file mode 100644 index 000000000000..7f6789e90123 --- /dev/null +++ b/device/delta/x86_64-delta_ag9032v1-r0/led_proc_init.soc @@ -0,0 +1,45 @@ +s CMIC_LEDUP0_PROGRAM_RAM 0 +s CMIC_LEDUP1_PROGRAM_RAM 0 + +led 0 stop +led 0 prog 02 00 60 E0 86 ED 2E E0 32 08 97 02 00 0E 00 60 E3 2E E0 32 00 32 01 B7 97 02 00 0E 00 12 E7 50 86 E0 86 E0 86 E0 86 E0 16 E7 61 EB 06 E3 67 4E 67 66 67 66 67 66 67 66 67 66 67 66 67 66 67 66 67 66 67 66 67 66 06 E0 D2 40 74 06 3A C0 D2 01 74 66 06 EB D2 00 70 62 16 ED 99 99 1A 00 71 62 77 66 32 0F 87 57 32 0E 87 57 +led 0 auto on +led 0 start +m CMIC_LEDUP0_PORT_ORDER_REMAP_0_3 REMAP_PORT_0=31 REMAP_PORT_1=30 REMAP_PORT_2=29 REMAP_PORT_3=28 +m CMIC_LEDUP0_PORT_ORDER_REMAP_4_7 REMAP_PORT_4=27 REMAP_PORT_5=26 REMAP_PORT_6=25 REMAP_PORT_7=24 +m CMIC_LEDUP0_PORT_ORDER_REMAP_8_11 REMAP_PORT_8=23 REMAP_PORT_9=22 REMAP_PORT_10=21 REMAP_PORT_11=20 +m CMIC_LEDUP0_PORT_ORDER_REMAP_12_15 REMAP_PORT_12=19 REMAP_PORT_13=18 REMAP_PORT_14=17 REMAP_PORT_15=16 +m CMIC_LEDUP0_PORT_ORDER_REMAP_16_19 REMAP_PORT_16=15 REMAP_PORT_17=14 REMAP_PORT_18=13 REMAP_PORT_19=12 +m CMIC_LEDUP0_PORT_ORDER_REMAP_20_23 REMAP_PORT_20=11 REMAP_PORT_21=10 REMAP_PORT_22=9 REMAP_PORT_23=8 +m CMIC_LEDUP0_PORT_ORDER_REMAP_24_27 REMAP_PORT_24=7 REMAP_PORT_25=6 REMAP_PORT_26=5 REMAP_PORT_27=4 +m CMIC_LEDUP0_PORT_ORDER_REMAP_28_31 REMAP_PORT_28=3 REMAP_PORT_29=2 REMAP_PORT_30=1 REMAP_PORT_31=0 +m CMIC_LEDUP0_PORT_ORDER_REMAP_32_35 REMAP_PORT_32=63 REMAP_PORT_33=62 REMAP_PORT_34=61 REMAP_PORT_35=60 +m CMIC_LEDUP0_PORT_ORDER_REMAP_36_39 REMAP_PORT_36=59 REMAP_PORT_37=58 REMAP_PORT_38=57 REMAP_PORT_39=56 +m CMIC_LEDUP0_PORT_ORDER_REMAP_40_43 REMAP_PORT_40=55 REMAP_PORT_41=54 REMAP_PORT_42=53 REMAP_PORT_43=52 +m CMIC_LEDUP0_PORT_ORDER_REMAP_44_47 REMAP_PORT_44=51 REMAP_PORT_45=50 REMAP_PORT_46=49 REMAP_PORT_47=48 +m CMIC_LEDUP0_PORT_ORDER_REMAP_48_51 REMAP_PORT_48=47 REMAP_PORT_49=46 REMAP_PORT_50=45 REMAP_PORT_51=44 +m CMIC_LEDUP0_PORT_ORDER_REMAP_52_55 REMAP_PORT_52=43 REMAP_PORT_53=42 REMAP_PORT_54=41 REMAP_PORT_55=40 +m CMIC_LEDUP0_PORT_ORDER_REMAP_56_59 REMAP_PORT_56=39 REMAP_PORT_57=38 REMAP_PORT_58=37 REMAP_PORT_59=36 +m CMIC_LEDUP0_PORT_ORDER_REMAP_60_63 REMAP_PORT_60=35 REMAP_PORT_61=34 REMAP_PORT_62=33 REMAP_PORT_63=32 + +led 1 stop +led 1 prog 02 00 60 E0 86 ED 2E E0 32 08 97 02 00 0E 00 60 E3 2E E0 32 00 32 01 B7 97 02 00 0E 00 12 E7 50 86 E0 86 E0 86 E0 86 E0 16 E7 61 EB 06 E3 67 4E 67 66 67 66 67 66 67 66 67 66 67 66 67 66 67 66 67 66 67 66 67 66 06 E0 D2 40 74 06 3A C0 D2 01 74 66 06 EB D2 00 70 62 16 ED 99 99 1A 00 71 62 77 66 32 0F 87 57 32 0E 87 57 +led 1 auto on +led 1 start +m CMIC_LEDUP1_PORT_ORDER_REMAP_0_3 REMAP_PORT_0=3 REMAP_PORT_1=2 REMAP_PORT_2=1 REMAP_PORT_3=0 +m CMIC_LEDUP1_PORT_ORDER_REMAP_4_7 REMAP_PORT_4=7 REMAP_PORT_5=6 REMAP_PORT_6=5 REMAP_PORT_7=4 +m CMIC_LEDUP1_PORT_ORDER_REMAP_8_11 REMAP_PORT_8=11 REMAP_PORT_9=10 REMAP_PORT_10=9 REMAP_PORT_11=8 +m CMIC_LEDUP1_PORT_ORDER_REMAP_12_15 REMAP_PORT_12=15 REMAP_PORT_13=14 REMAP_PORT_14=13 REMAP_PORT_15=12 +m CMIC_LEDUP1_PORT_ORDER_REMAP_16_19 REMAP_PORT_16=19 REMAP_PORT_17=18 REMAP_PORT_18=17 REMAP_PORT_19=16 +m CMIC_LEDUP1_PORT_ORDER_REMAP_20_23 REMAP_PORT_20=23 REMAP_PORT_21=22 REMAP_PORT_22=21 REMAP_PORT_23=20 +m CMIC_LEDUP1_PORT_ORDER_REMAP_24_27 REMAP_PORT_24=27 REMAP_PORT_25=26 REMAP_PORT_26=25 REMAP_PORT_27=24 +m CMIC_LEDUP1_PORT_ORDER_REMAP_28_31 REMAP_PORT_28=31 REMAP_PORT_29=30 REMAP_PORT_30=29 REMAP_PORT_31=28 +m CMIC_LEDUP1_PORT_ORDER_REMAP_32_35 REMAP_PORT_32=35 REMAP_PORT_33=34 REMAP_PORT_34=33 REMAP_PORT_35=32 +m CMIC_LEDUP1_PORT_ORDER_REMAP_36_39 REMAP_PORT_36=39 REMAP_PORT_37=38 REMAP_PORT_38=37 REMAP_PORT_39=36 +m CMIC_LEDUP1_PORT_ORDER_REMAP_40_43 REMAP_PORT_40=43 REMAP_PORT_41=42 REMAP_PORT_42=41 REMAP_PORT_43=40 +m CMIC_LEDUP1_PORT_ORDER_REMAP_44_47 REMAP_PORT_44=47 REMAP_PORT_45=46 REMAP_PORT_46=45 REMAP_PORT_47=44 +m CMIC_LEDUP1_PORT_ORDER_REMAP_48_51 REMAP_PORT_48=51 REMAP_PORT_49=50 REMAP_PORT_50=49 REMAP_PORT_51=48 +m CMIC_LEDUP1_PORT_ORDER_REMAP_52_55 REMAP_PORT_52=55 REMAP_PORT_53=54 REMAP_PORT_54=53 REMAP_PORT_55=52 +m CMIC_LEDUP1_PORT_ORDER_REMAP_56_59 REMAP_PORT_56=59 REMAP_PORT_57=58 REMAP_PORT_58=57 REMAP_PORT_59=56 +m CMIC_LEDUP1_PORT_ORDER_REMAP_60_63 REMAP_PORT_60=63 REMAP_PORT_61=62 REMAP_PORT_62=61 REMAP_PORT_63=60 + diff --git a/device/delta/x86_64-delta_ag9032v1-r0/minigraph.xml b/device/delta/x86_64-delta_ag9032v1-r0/minigraph.xml new file mode 100644 index 000000000000..db8d62440534 --- /dev/null +++ b/device/delta/x86_64-delta_ag9032v1-r0/minigraph.xml @@ -0,0 +1,1079 @@ + + + + + + ARISTA01T0 + 10.0.0.33 + switch1 + 10.0.0.32 + 1 + 180 + 60 + + + switch1 + 10.0.0.0 + ARISTA01T2 + 10.0.0.1 + 1 + 180 + 60 + + + ARISTA02T0 + 10.0.0.35 + switch1 + 10.0.0.34 + 1 + 180 + 60 + + + switch1 + 10.0.0.2 + ARISTA02T2 + 10.0.0.3 + 1 + 180 + 60 + + + ARISTA03T0 + 10.0.0.37 + switch1 + 10.0.0.36 + 1 + 180 + 60 + + + switch1 + 10.0.0.4 + ARISTA03T2 + 10.0.0.5 + 1 + 180 + 60 + + + ARISTA04T0 + 10.0.0.39 + switch1 + 10.0.0.38 + 1 + 180 + 60 + + + switch1 + 10.0.0.6 + ARISTA04T2 + 10.0.0.7 + 1 + 180 + 60 + + + ARISTA05T0 + 10.0.0.41 + switch1 + 10.0.0.40 + 1 + 180 + 60 + + + switch1 + 10.0.0.8 + ARISTA05T2 + 10.0.0.9 + 1 + 180 + 60 + + + ARISTA06T0 + 10.0.0.43 + switch1 + 10.0.0.42 + 1 + 180 + 60 + + + switch1 + 10.0.0.10 + ARISTA06T2 + 10.0.0.11 + 1 + 180 + 60 + + + ARISTA07T0 + 10.0.0.45 + switch1 + 10.0.0.44 + 1 + 180 + 60 + + + switch1 + 10.0.0.12 + ARISTA07T2 + 10.0.0.13 + 1 + 180 + 60 + + + ARISTA08T0 + 10.0.0.47 + switch1 + 10.0.0.46 + 1 + 180 + 60 + + + switch1 + 10.0.0.14 + ARISTA08T2 + 10.0.0.15 + 1 + 180 + 60 + + + ARISTA09T0 + 10.0.0.49 + switch1 + 10.0.0.48 + 1 + 180 + 60 + + + switch1 + 10.0.0.16 + ARISTA09T2 + 10.0.0.17 + 1 + 180 + 60 + + + ARISTA10T0 + 10.0.0.51 + switch1 + 10.0.0.50 + 1 + 180 + 60 + + + switch1 + 10.0.0.18 + ARISTA10T2 + 10.0.0.19 + 1 + 180 + 60 + + + ARISTA11T0 + 10.0.0.53 + switch1 + 10.0.0.52 + 1 + 180 + 60 + + + switch1 + 10.0.0.20 + ARISTA11T2 + 10.0.0.21 + 1 + 180 + 60 + + + ARISTA12T0 + 10.0.0.55 + switch1 + 10.0.0.54 + 1 + 180 + 60 + + + switch1 + 10.0.0.22 + ARISTA12T2 + 10.0.0.23 + 1 + 180 + 60 + + + ARISTA13T0 + 10.0.0.57 + switch1 + 10.0.0.56 + 1 + 180 + 60 + + + switch1 + 10.0.0.24 + ARISTA13T2 + 10.0.0.25 + 1 + 180 + 60 + + + ARISTA14T0 + 10.0.0.59 + switch1 + 10.0.0.58 + 1 + 180 + 60 + + + switch1 + 10.0.0.26 + ARISTA14T2 + 10.0.0.27 + 1 + 180 + 60 + + + ARISTA15T0 + 10.0.0.61 + switch1 + 10.0.0.60 + 1 + 180 + 60 + + + switch1 + 10.0.0.28 + ARISTA15T2 + 10.0.0.29 + 1 + 180 + 60 + + + ARISTA16T0 + 10.0.0.63 + switch1 + 10.0.0.62 + 1 + 180 + 60 + + + switch1 + 10.0.0.30 + ARISTA16T2 + 10.0.0.31 + 1 + 180 + 60 + + + + + 65100 + switch1 + + +
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 + + + + + + + + switch1 + + + + + + hundredGigE1/1 + 10.0.0.0/31 + + + + hundredGigE1/2 + 10.0.0.2/31 + + + + hundredGigE1/3 + 10.0.0.4/31 + + + + hundredGigE1/4 + 10.0.0.6/31 + + + + hundredGigE1/5 + 10.0.0.8/31 + + + + hundredGigE1/6 + 10.0.0.10/31 + + + + hundredGigE1/7 + 10.0.0.12/31 + + + + hundredGigE1/8 + 10.0.0.14/31 + + + + hundredGigE1/9 + 10.0.0.16/31 + + + + hundredGigE1/10 + 10.0.0.18/31 + + + + hundredGigE1/11 + 10.0.0.20/31 + + + + hundredGigE1/12 + 10.0.0.22/31 + + + + hundredGigE1/13 + 10.0.0.24/31 + + + + hundredGigE1/14 + 10.0.0.26/31 + + + + hundredGigE1/15 + 10.0.0.28/31 + + + + hundredGigE1/16 + 10.0.0.30/31 + + + + hundredGigE1/17 + 10.0.0.32/31 + + + + hundredGigE1/18 + 10.0.0.34/31 + + + + hundredGigE1/19 + 10.0.0.36/31 + + + + hundredGigE1/20 + 10.0.0.38/31 + + + + hundredGigE1/21 + 10.0.0.40/31 + + + + hundredGigE1/22 + 10.0.0.42/31 + + + + hundredGigE1/23 + 10.0.0.44/31 + + + + hundredGigE1/24 + 10.0.0.46/31 + + + + hundredGigE1/25 + 10.0.0.48/31 + + + + hundredGigE1/26 + 10.0.0.50/31 + + + + hundredGigE1/27 + 10.0.0.52/31 + + + + hundredGigE1/28 + 10.0.0.54/31 + + + + hundredGigE1/29 + 10.0.0.56/31 + + + + hundredGigE1/30 + 10.0.0.58/31 + + + + hundredGigE1/31 + 10.0.0.60/31 + + + + hundredGigE1/32 + 10.0.0.62/31 + + + + + + + + + + + + DeviceInterfaceLink + switch1 + hundredGigE1/1 + ARISTA01T2 + Ethernet1 + + + DeviceInterfaceLink + switch1 + hundredGigE1/2 + ARISTA02T2 + Ethernet1 + + + DeviceInterfaceLink + switch1 + hundredGigE1/3 + ARISTA03T2 + Ethernet1 + + + DeviceInterfaceLink + switch1 + hundredGigE1/4 + ARISTA04T2 + Ethernet1 + + + DeviceInterfaceLink + switch1 + hundredGigE1/5 + ARISTA05T2 + Ethernet1 + + + DeviceInterfaceLink + switch1 + hundredGigE1/6 + ARISTA06T2 + Ethernet1 + + + DeviceInterfaceLink + switch1 + hundredGigE1/7 + ARISTA07T2 + Ethernet1 + + + DeviceInterfaceLink + switch1 + hundredGigE1/8 + ARISTA08T2 + Ethernet1 + + + DeviceInterfaceLink + switch1 + hundredGigE1/9 + ARISTA09T2 + Ethernet1 + + + DeviceInterfaceLink + switch1 + hundredGigE1/10 + ARISTA10T2 + Ethernet1 + + + DeviceInterfaceLink + switch1 + hundredGigE1/11 + ARISTA11T2 + Ethernet1 + + + DeviceInterfaceLink + switch1 + hundredGigE1/12 + ARISTA12T2 + Ethernet1 + + + DeviceInterfaceLink + switch1 + hundredGigE1/13 + ARISTA13T2 + Ethernet1 + + + DeviceInterfaceLink + switch1 + hundredGigE1/14 + ARISTA14T2 + Ethernet1 + + + DeviceInterfaceLink + switch1 + hundredGigE1/15 + ARISTA15T2 + Ethernet1 + + + DeviceInterfaceLink + switch1 + hundredGigE1/16 + ARISTA16T2 + Ethernet1 + + + DeviceInterfaceLink + switch1 + hundredGigE1/17 + ARISTA01T0 + Ethernet1 + + + DeviceInterfaceLink + switch1 + hundredGigE1/18 + ARISTA02T0 + Ethernet1 + + + DeviceInterfaceLink + switch1 + hundredGigE1/19 + ARISTA03T0 + Ethernet1 + + + DeviceInterfaceLink + switch1 + hundredGigE1/20 + ARISTA04T0 + Ethernet1 + + + DeviceInterfaceLink + switch1 + hundredGigE1/21 + ARISTA05T0 + Ethernet1 + + + DeviceInterfaceLink + switch1 + hundredGigE1/22 + ARISTA06T0 + Ethernet1 + + + DeviceInterfaceLink + switch1 + hundredGigE1/23 + ARISTA07T0 + Ethernet1 + + + DeviceInterfaceLink + switch1 + hundredGigE1/24 + ARISTA08T0 + Ethernet1 + + + DeviceInterfaceLink + switch1 + hundredGigE1/25 + ARISTA09T0 + Ethernet1 + + + DeviceInterfaceLink + switch1 + hundredGigE1/26 + ARISTA10T0 + Ethernet1 + + + DeviceInterfaceLink + switch1 + hundredGigE1/27 + ARISTA11T0 + Ethernet1 + + + DeviceInterfaceLink + switch1 + hundredGigE1/28 + ARISTA12T0 + Ethernet1 + + + DeviceInterfaceLink + switch1 + hundredGigE1/29 + ARISTA13T0 + Ethernet1 + + + DeviceInterfaceLink + switch1 + hundredGigE1/30 + ARISTA14T0 + Ethernet1 + + + DeviceInterfaceLink + switch1 + hundredGigE1/31 + ARISTA15T0 + Ethernet1 + + + DeviceInterfaceLink + switch1 + hundredGigE1/32 + ARISTA16T0 + Ethernet1 + + + + + switch1 + Delta-ag9032v1 + + + + + + + switch1 + + + 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 + + + + + + + switch1 + Delta-ag9032v1 +
diff --git a/device/delta/x86_64-delta_ag9032v1-r0/plugins/eeprom.py b/device/delta/x86_64-delta_ag9032v1-r0/plugins/eeprom.py new file mode 100644 index 000000000000..786e1fdc85e3 --- /dev/null +++ b/device/delta/x86_64-delta_ag9032v1-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 = "/sys/devices/pci0000:00/0000:00:13.0/i2c-1/i2c-2/2-0053/eeprom" + super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/delta/x86_64-delta_ag9032v1-r0/plugins/sfputil.py b/device/delta/x86_64-delta_ag9032v1-r0/plugins/sfputil.py new file mode 100644 index 000000000000..54d69446b1d8 --- /dev/null +++ b/device/delta/x86_64-delta_ag9032v1-r0/plugins/sfputil.py @@ -0,0 +1,175 @@ +# sfputil.py +# +# Platform-specific SFP transceiver interface for SONiC +# + +try: + import time + 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 = 50 + + _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 = "/sys/class/i2c-adapter/i2c-{0}/{0}-0050/eeprom" + + 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("/sys/devices/platform/delta-ag9032v1-cpld.0/sfp_present") + 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) + + # Mask off the bit corresponding to our port + mask = (1 << port_num) + + # ModPrsL is active low + if reg_value & mask == 0: + 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 + + try: + reg_file = open("/sys/devices/platform/delta-ag9032v1-cpld.0/sfp_lpmode") + except IOError as e: + print "Error: unable to open file: %s" % str(e) + + content = reg_file.readline().rstrip() + + # content is a string containing the hex representation of the register + reg_value = int(content, 16) + + # Mask off the bit corresponding to our port + mask = (1 << port_num) + + # LPMode is active high + if reg_value & mask == 0: + return False + + return True + + def set_low_power_mode(self, port_num, lpmode): + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + try: + reg_file = open("/sys/devices/platform/delta-ag9032v1-cpld.0/sfp_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) + + # Mask off the bit corresponding to our port + mask = (1 << port_num) + + # 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) + + reg_file.seek(0) + reg_file.write(content) + reg_file.close() + + return True + + def reset(self, port_num): + QSFP_RESET_REGISTER_DEVICE_FILE = "/sys/devices/platform/delta-ag9032v1-cpld.0/sfp_reset" + + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + try: + reg_file = open(QSFP_RESET_REGISTER_DEVICE_FILE, "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) + + # Mask off the bit corresponding to our port + mask = (1 << port_num) + + # 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)) + 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(QSFP_RESET_REGISTER_DEVICE_FILE, "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)) + reg_file.close() + + return True \ No newline at end of file diff --git a/device/delta/x86_64-delta_ag9032v1-r0/sensors.conf b/device/delta/x86_64-delta_ag9032v1-r0/sensors.conf new file mode 100644 index 000000000000..d3b2aea2a5af --- /dev/null +++ b/device/delta/x86_64-delta_ag9032v1-r0/sensors.conf @@ -0,0 +1,61 @@ +# libsensors configuration file for DCS-7060CX-32S +# ------------------------------------------------ +# + +bus "i2c-2" "i2c-1-mux (chan_id 0)" +bus "i2c-3" "i2c-1-mux (chan_id 1)" +bus "i2c-4" "i2c-1-mux (chan_id 2)" +bus "i2c-7" "i2c-1-mux (chan_id 5)" + + +# tmp75-i2c-2-4d CPU below side thermal sensor. +# tmp75-i2c-3-4f Wind thermal sensor. +# tmp75-i2c-7-4c MAC up side thermal sensor. +# tmp75-i2c-7-4d MAC down side thermal sensor. +# tmp75-i2c-7-4e Surroundings thermal sensor. + +chip "tmp75-i2c-2-4d" + label temp1 "CPU below side thermal sensor" + set temp1_max 60 + set temp1_max_hyst 55 + +chip "tmp75-i2c-*-4f" + label temp1 "Wind thermal sensor" + set temp1_max 65 + set temp1_max_hyst 60 +chip "tmp75-i2c-7-4c" + label temp1 "MAC up side thermal sensor" + set temp1_max 80 + set temp1_max_hyst 75 +chip "tmp75-i2c-7-4d" + label temp1 "MAC down side thermal sensor" + set temp1_max 75 + set temp1_max_hyst 70 +chip "tmp75-i2c-7-4e" + label temp1 "Surroundings thermal sensor" + set temp1_max 65 + set temp1_max_hyst 60 + + +chip "emc2305-i2c-3-2d" + label fan1 "FANTRAY 1 REAR" + label fan2 "FANTRAY 2 REAR" + label fan3 "FANTRAY 3 REAR" + label fan4 "FANTRAY 4 REAR" + label fan5 "FANTRAY 5 REAR" +chip "emc2305-i2c-3-2c" + label fan1 "FANTRAY 1 FRONT" + label fan2 "FANTRAY 2 FRONT" + label fan3 "FANTRAY 3 FRONT" + label fan4 "FANTRAY 4 FRONT" + label fan5 "FANTRAY 5 FRONT" +chip "pmbus-i2c-4-50" + label temp1 "Fan of power supply controller 1 sensor 1" + label temp2 "Fan of Power supply controller 1 sensor 2" + +chip "pmbus-i2c-4-40" + label temp1 "Power supply 1 hotspot sensor" + +chip "pmbus-i2c-4-40" + label temp1 "Power supply 2 hotspot sensor" + diff --git a/device/ingrasys/x86_64-ingrasys_s8810_32q-r0/minigraph.xml b/device/ingrasys/x86_64-ingrasys_s8810_32q-r0/minigraph.xml index ab90ada24274..991591585cca 100644 --- a/device/ingrasys/x86_64-ingrasys_s8810_32q-r0/minigraph.xml +++ b/device/ingrasys/x86_64-ingrasys_s8810_32q-r0/minigraph.xml @@ -103,7 +103,7 @@ 40000 DeviceInterfaceLink - OCPSCH8810MS + OCPSCH0104002MS Ethernet0 OCPSCH01040HHLF Ethernet52 @@ -111,7 +111,7 @@ - OCPSCH8810HHLF + OCPSCH01040HHLF INGRASYS-S8810-32Q diff --git a/device/ingrasys/x86_64-ingrasys_s8810_32q-r0/sensors.conf b/device/ingrasys/x86_64-ingrasys_s8810_32q-r0/sensors.conf index 7ab599698225..8332fbdf9086 100644 --- a/device/ingrasys/x86_64-ingrasys_s8810_32q-r0/sensors.conf +++ b/device/ingrasys/x86_64-ingrasys_s8810_32q-r0/sensors.conf @@ -9,8 +9,8 @@ chip "jc42-*" chip "w83795adg-*" label in0 "ROV" - set in0_min 1 * 0.97 - set in0_max 1 * 1.033 + set in0_min 1.025 * 0.98 + set in0_max 1.025 * 1.02 ignore in1 ignore in2 label in3 "1.0V" diff --git a/device/ingrasys/x86_64-ingrasys_s8900_54xc-r0/INGRASYS-S8900-54XC/port_config.ini b/device/ingrasys/x86_64-ingrasys_s8900_54xc-r0/INGRASYS-S8900-54XC/port_config.ini index 3350b68172cb..079bb63455f2 100644 --- a/device/ingrasys/x86_64-ingrasys_s8900_54xc-r0/INGRASYS-S8900-54XC/port_config.ini +++ b/device/ingrasys/x86_64-ingrasys_s8900_54xc-r0/INGRASYS-S8900-54XC/port_config.ini @@ -1,55 +1,55 @@ # name lanes alias index -Ethernet0 1 Ethernet1 0 -Ethernet1 2 Ethernet2 1 -Ethernet2 3 Ethernet3 2 -Ethernet3 4 Ethernet4 3 -Ethernet4 5 Ethernet5 4 -Ethernet5 6 Ethernet6 5 -Ethernet6 7 Ethernet7 6 -Ethernet7 8 Ethernet8 7 -Ethernet8 9 Ethernet9 8 -Ethernet9 10 Ethernet10 9 -Ethernet10 11 Ethernet11 10 -Ethernet11 12 Ethernet12 11 -Ethernet12 21 Ethernet13 12 -Ethernet13 22 Ethernet14 13 -Ethernet14 23 Ethernet15 14 -Ethernet15 24 Ethernet16 15 -Ethernet16 33 Ethernet17 16 -Ethernet17 34 Ethernet18 17 -Ethernet18 35 Ethernet19 18 -Ethernet19 36 Ethernet20 19 -Ethernet20 37 Ethernet21 20 -Ethernet21 38 Ethernet22 21 -Ethernet22 39 Ethernet23 22 -Ethernet23 40 Ethernet24 23 -Ethernet24 41 Ethernet25 24 -Ethernet25 42 Ethernet26 25 -Ethernet26 43 Ethernet27 26 -Ethernet27 44 Ethernet28 27 -Ethernet28 49 Ethernet29 28 -Ethernet29 50 Ethernet30 29 -Ethernet30 51 Ethernet31 30 -Ethernet31 52 Ethernet32 31 -Ethernet32 53 Ethernet33 32 -Ethernet33 54 Ethernet34 33 -Ethernet34 55 Ethernet35 34 -Ethernet35 56 Ethernet36 35 -Ethernet36 65 Ethernet37 36 -Ethernet37 66 Ethernet38 37 -Ethernet38 67 Ethernet39 38 -Ethernet39 68 Ethernet40 39 -Ethernet40 69 Ethernet41 40 -Ethernet41 70 Ethernet42 41 -Ethernet42 71 Ethernet43 42 -Ethernet43 72 Ethernet44 43 -Ethernet44 81 Ethernet45 44 -Ethernet45 82 Ethernet46 45 -Ethernet46 83 Ethernet47 46 -Ethernet47 84 Ethernet48 47 -Ethernet48 85,86,87,88 Ethernet49/1 48 -Ethernet52 97,98,99,100 Ethernet50/1 49 -Ethernet56 101,102,103,104 Ethernet51/1 50 -Ethernet60 105,106,107,108 Ethernet52/1 51 -Ethernet64 109,110,111,112 Ethernet53/1 52 -Ethernet68 117,118,119,120 Ethernet54/1 53 +Ethernet0 1 Ethernet1/1 0 +Ethernet1 2 Ethernet2/1 1 +Ethernet2 3 Ethernet3/1 2 +Ethernet3 4 Ethernet4/1 3 +Ethernet4 5 Ethernet5/1 4 +Ethernet5 6 Ethernet6/1 5 +Ethernet6 7 Ethernet7/1 6 +Ethernet7 8 Ethernet8/1 7 +Ethernet8 9 Ethernet9/1 8 +Ethernet9 10 Ethernet10/1 9 +Ethernet10 11 Ethernet11/1 10 +Ethernet11 12 Ethernet12/1 11 +Ethernet12 21 Ethernet13/1 12 +Ethernet13 22 Ethernet14/1 13 +Ethernet14 23 Ethernet15/1 14 +Ethernet15 24 Ethernet16/1 15 +Ethernet16 33 Ethernet17/1 16 +Ethernet17 34 Ethernet18/1 17 +Ethernet18 35 Ethernet19/1 18 +Ethernet19 36 Ethernet20/1 19 +Ethernet20 37 Ethernet21/1 20 +Ethernet21 38 Ethernet22/1 21 +Ethernet22 39 Ethernet23/1 22 +Ethernet23 40 Ethernet24/1 23 +Ethernet24 41 Ethernet25/1 24 +Ethernet25 42 Ethernet26/1 25 +Ethernet26 43 Ethernet27/1 26 +Ethernet27 44 Ethernet28/1 27 +Ethernet28 49 Ethernet29/1 28 +Ethernet29 50 Ethernet30/1 29 +Ethernet30 51 Ethernet31/1 30 +Ethernet31 52 Ethernet32/1 31 +Ethernet32 53 Ethernet33/1 32 +Ethernet33 54 Ethernet34/1 33 +Ethernet34 55 Ethernet35/1 34 +Ethernet35 56 Ethernet36/1 35 +Ethernet36 65 Ethernet37/1 36 +Ethernet37 66 Ethernet38/1 37 +Ethernet38 67 Ethernet39/1 38 +Ethernet39 68 Ethernet40/1 39 +Ethernet40 69 Ethernet41/1 40 +Ethernet41 70 Ethernet42/1 41 +Ethernet42 71 Ethernet43/1 42 +Ethernet43 72 Ethernet44/1 43 +Ethernet44 81 Ethernet45/1 44 +Ethernet45 82 Ethernet46/1 45 +Ethernet46 83 Ethernet47/1 46 +Ethernet47 84 Ethernet48/1 47 +Ethernet48 85,86,87,88 Ethernet52/1 48 +Ethernet52 97,98,99,100 Ethernet56/1 49 +Ethernet56 101,102,103,104 Ethernet60/1 50 +Ethernet60 105,106,107,108 Ethernet64/1 51 +Ethernet64 109,110,111,112 Ethernet68/1 52 +Ethernet68 117,118,119,120 Ethernet69/1 53 diff --git a/device/ingrasys/x86_64-ingrasys_s8900_64xc-r0/INGRASYS-S8900-64XC/port_config.ini b/device/ingrasys/x86_64-ingrasys_s8900_64xc-r0/INGRASYS-S8900-64XC/port_config.ini index b950538edba7..385056e6e8f0 100644 --- a/device/ingrasys/x86_64-ingrasys_s8900_64xc-r0/INGRASYS-S8900-64XC/port_config.ini +++ b/device/ingrasys/x86_64-ingrasys_s8900_64xc-r0/INGRASYS-S8900-64XC/port_config.ini @@ -1,52 +1,52 @@ # name lanes alias index -Ethernet0 17 Ethernet1 0 -Ethernet1 18 Ethernet2 1 -Ethernet2 19 Ethernet3 2 -Ethernet3 20 Ethernet4 3 -Ethernet4 24 Ethernet5 4 -Ethernet5 23 Ethernet6 5 -Ethernet6 22 Ethernet7 6 -Ethernet7 21 Ethernet8 7 -Ethernet8 28 Ethernet9 8 -Ethernet9 27 Ethernet10 9 -Ethernet10 26 Ethernet11 10 -Ethernet11 25 Ethernet12 11 -Ethernet12 32 Ethernet13 12 -Ethernet13 31 Ethernet14 13 -Ethernet14 30 Ethernet15 14 -Ethernet15 29 Ethernet16 15 -Ethernet16 1 Ethernet17 16 -Ethernet17 2 Ethernet18 17 -Ethernet18 3 Ethernet19 18 -Ethernet19 4 Ethernet20 19 -Ethernet20 8 Ethernet21 20 -Ethernet21 7 Ethernet22 21 -Ethernet22 6 Ethernet23 22 -Ethernet23 5 Ethernet24 23 -Ethernet24 12 Ethernet25 24 -Ethernet25 11 Ethernet26 25 -Ethernet26 10 Ethernet27 26 -Ethernet27 9 Ethernet28 27 -Ethernet28 13 Ethernet29 28 -Ethernet29 14 Ethernet30 29 -Ethernet30 15 Ethernet31 30 -Ethernet31 16 Ethernet32 31 -Ethernet32 33 Ethernet33 32 -Ethernet33 34 Ethernet34 33 -Ethernet34 35 Ethernet35 34 -Ethernet35 36 Ethernet36 35 -Ethernet36 38 Ethernet37 36 -Ethernet37 39 Ethernet38 37 -Ethernet38 40 Ethernet39 38 -Ethernet39 37 Ethernet40 39 -Ethernet40 41 Ethernet41 40 -Ethernet41 42 Ethernet42 41 -Ethernet42 43 Ethernet43 42 -Ethernet43 44 Ethernet44 43 -Ethernet44 48 Ethernet45 44 -Ethernet45 45 Ethernet46 45 -Ethernet46 46 Ethernet47 46 -Ethernet47 47 Ethernet48 47 +Ethernet0 17 Ethernet1/1 0 +Ethernet1 18 Ethernet2/1 1 +Ethernet2 19 Ethernet3/1 2 +Ethernet3 20 Ethernet4/1 3 +Ethernet4 24 Ethernet5/1 4 +Ethernet5 23 Ethernet6/1 5 +Ethernet6 22 Ethernet7/1 6 +Ethernet7 21 Ethernet8/1 7 +Ethernet8 28 Ethernet9/1 8 +Ethernet9 27 Ethernet10/1 9 +Ethernet10 26 Ethernet11/1 10 +Ethernet11 25 Ethernet12/1 11 +Ethernet12 32 Ethernet13/1 12 +Ethernet13 31 Ethernet14/1 13 +Ethernet14 30 Ethernet15/1 14 +Ethernet15 29 Ethernet16/1 15 +Ethernet16 1 Ethernet17/1 16 +Ethernet17 2 Ethernet18/1 17 +Ethernet18 3 Ethernet19/1 18 +Ethernet19 4 Ethernet20/1 19 +Ethernet20 8 Ethernet21/1 20 +Ethernet21 7 Ethernet22/1 21 +Ethernet22 6 Ethernet23/1 22 +Ethernet23 5 Ethernet24/1 23 +Ethernet24 12 Ethernet25/1 24 +Ethernet25 11 Ethernet26/1 25 +Ethernet26 10 Ethernet27/1 26 +Ethernet27 9 Ethernet28/1 27 +Ethernet28 13 Ethernet29/1 28 +Ethernet29 14 Ethernet30/1 29 +Ethernet30 15 Ethernet31/1 30 +Ethernet31 16 Ethernet32/1 31 +Ethernet32 33 Ethernet33/1 32 +Ethernet33 34 Ethernet34/1 33 +Ethernet34 35 Ethernet35/1 34 +Ethernet35 36 Ethernet36/1 35 +Ethernet36 38 Ethernet37/1 36 +Ethernet37 39 Ethernet38/1 37 +Ethernet38 40 Ethernet39/1 38 +Ethernet39 37 Ethernet40/1 39 +Ethernet40 41 Ethernet41/1 40 +Ethernet41 42 Ethernet42/1 41 +Ethernet42 43 Ethernet43/1 42 +Ethernet43 44 Ethernet44/1 43 +Ethernet44 48 Ethernet45/1 44 +Ethernet45 45 Ethernet46/1 45 +Ethernet46 46 Ethernet47/1 46 +Ethernet47 47 Ethernet48/1 47 Ethernet48 49,50,51,52 Ethernet49/1 48 Ethernet52 53,54,55,56 Ethernet50/1 49 Ethernet56 57,58,59,60 Ethernet51/1 50 diff --git a/device/ingrasys/x86_64-ingrasys_s9200_64x-r0/INGRASYS-S9200-64X/port_config.ini b/device/ingrasys/x86_64-ingrasys_s9200_64x-r0/INGRASYS-S9200-64X/port_config.ini new file mode 100644 index 000000000000..f1127a5aa046 --- /dev/null +++ b/device/ingrasys/x86_64-ingrasys_s9200_64x-r0/INGRASYS-S9200-64X/port_config.ini @@ -0,0 +1,65 @@ +# name lanes alias index +Ethernet0 1,2,3,4 Ethernet1/1 0 +Ethernet4 5,6,7,8 Ethernet2/1 1 +Ethernet8 17,18,19,20 Ethernet3/1 2 +Ethernet12 21,22,23,24 Ethernet4/1 3 +Ethernet16 33,34,35,36 Ethernet5/1 4 +Ethernet20 37,38,39,40 Ethernet6/1 5 +Ethernet24 49,50,51,52 Ethernet7/1 6 +Ethernet28 53,54,55,56 Ethernet8/1 7 +Ethernet32 65,66,67,68 Ethernet9/1 8 +Ethernet36 69,70,71,72 Ethernet10/1 9 +Ethernet40 81,82,83,84 Ethernet11/1 10 +Ethernet44 85,86,87,88 Ethernet12/1 11 +Ethernet48 97,98,99,100 Ethernet13/1 12 +Ethernet52 101,102,103,104 Ethernet14/1 13 +Ethernet56 113,114,115,116 Ethernet15/1 14 +Ethernet60 117,118,119,120 Ethernet16/1 15 +Ethernet64 129,130,131,132 Ethernet17/1 16 +Ethernet68 133,134,135,136 Ethernet18/1 17 +Ethernet72 145,146,147,148 Ethernet19/1 18 +Ethernet76 149,150,151,152 Ethernet20/1 19 +Ethernet80 161,162,163,164 Ethernet21/1 20 +Ethernet84 165,166,167,168 Ethernet22/1 21 +Ethernet88 177,178,179,180 Ethernet23/1 22 +Ethernet92 181,182,183,184 Ethernet24/1 23 +Ethernet96 193,194,195,196 Ethernet25/1 24 +Ethernet100 197,198,199,200 Ethernet26/1 25 +Ethernet104 209,210,211,212 Ethernet27/1 26 +Ethernet108 213,214,215,216 Ethernet28/1 27 +Ethernet112 225,226,227,228 Ethernet29/1 28 +Ethernet116 229,230,231,232 Ethernet30/1 29 +Ethernet120 241,242,243,244 Ethernet31/1 30 +Ethernet124 245,246,247,248 Ethernet32/1 31 +Ethernet128 9,10,11,12 Ethernet33/1 32 +Ethernet132 13,14,15,16 Ethernet34/1 33 +Ethernet136 25,26,27,28 Ethernet35/1 34 +Ethernet140 29,30,31,32 Ethernet36/1 35 +Ethernet144 41,42,43,44 Ethernet37/1 36 +Ethernet148 45,46,47,48 Ethernet38/1 37 +Ethernet152 57,58,59,60 Ethernet39/1 38 +Ethernet156 61,62,63,64 Ethernet40/1 39 +Ethernet160 73,74,75,76 Ethernet41/1 40 +Ethernet164 77,78,79,80 Ethernet42/1 41 +Ethernet168 89,90,91,92 Ethernet43/1 42 +Ethernet172 93,94,95,96 Ethernet44/1 43 +Ethernet176 105,106,107,108 Ethernet45/1 44 +Ethernet180 109,110,111,112 Ethernet46/1 45 +Ethernet184 121,122,123,124 Ethernet47/1 46 +Ethernet188 125,126,127,128 Ethernet48/1 47 +Ethernet192 137,138,139,140 Ethernet49/1 48 +Ethernet196 141,142,143,144 Ethernet50/1 49 +Ethernet200 153,154,155,156 Ethernet51/1 50 +Ethernet204 157,158,159,160 Ethernet52/1 51 +Ethernet208 169,170,171,172 Ethernet53/1 52 +Ethernet212 173,174,175,176 Ethernet54/1 53 +Ethernet216 185,186,187,188 Ethernet55/1 54 +Ethernet220 189,190,191,192 Ethernet56/1 55 +Ethernet224 201,202,203,204 Ethernet57/1 56 +Ethernet228 205,206,207,208 Ethernet58/1 57 +Ethernet232 217,218,219,220 Ethernet59/1 58 +Ethernet236 221,222,223,224 Ethernet60/1 59 +Ethernet240 233,234,235,236 Ethernet61/1 60 +Ethernet244 237,238,239,240 Ethernet62/1 61 +Ethernet248 249,250,251,252 Ethernet63/1 62 +Ethernet252 253,254,255,256 Ethernet64/1 63 diff --git a/device/ingrasys/x86_64-ingrasys_s9200_64x-r0/INGRASYS-S9200-64X/sai.profile b/device/ingrasys/x86_64-ingrasys_s9200_64x-r0/INGRASYS-S9200-64X/sai.profile new file mode 100644 index 000000000000..20bbcc6a07df --- /dev/null +++ b/device/ingrasys/x86_64-ingrasys_s9200_64x-r0/INGRASYS-S9200-64X/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/etc/bcm/th2-s9200-64x100G.config.bcm diff --git a/device/ingrasys/x86_64-ingrasys_s9200_64x-r0/fancontrol b/device/ingrasys/x86_64-ingrasys_s9200_64x-r0/fancontrol new file mode 100644 index 000000000000..185ee3a2fc25 --- /dev/null +++ b/device/ingrasys/x86_64-ingrasys_s9200_64x-r0/fancontrol @@ -0,0 +1,9 @@ +INTERVAL=10 +DEVPATH=hwmon5=devices/pci0000:00/0000:00:1f.3/i2c-0/i2c-16/16-002f hwmon1=devices/pci0000:00/0000:00:1f.3/i2c-0/i2c-7/7-004d +DEVNAME=hwmon5=w83795adg +FCTEMPS=hwmon5/device/pwm2=hwmon1/temp1_input +FCFANS=hwmon5/device/pwm2=hwmon5/device/fan7_input hwmon5/device/pwm2=hwmon5/device/fan5_input hwmon5/device/pwm2=hwmon5/device/fan3_input hwmon5/device/pwm2=hwmon5/device/fan1_input +MINTEMP=hwmon5/device/pwm2=20 +MAXTEMP=hwmon5/device/pwm2=60 +MINSTART=hwmon5/device/pwm2=75 +MINSTOP=hwmon5/device/pwm2=22 diff --git a/device/ingrasys/x86_64-ingrasys_s9200_64x-r0/installer.conf b/device/ingrasys/x86_64-ingrasys_s9200_64x-r0/installer.conf new file mode 100644 index 000000000000..925a32fc0c3a --- /dev/null +++ b/device/ingrasys/x86_64-ingrasys_s9200_64x-r0/installer.conf @@ -0,0 +1,3 @@ +CONSOLE_PORT=0x3f8 +CONSOLE_DEV=0 +CONSOLE_SPEED=115200 diff --git a/device/ingrasys/x86_64-ingrasys_s9200_64x-r0/led_proc_init.soc b/device/ingrasys/x86_64-ingrasys_s9200_64x-r0/led_proc_init.soc new file mode 100644 index 000000000000..774923ff868d --- /dev/null +++ b/device/ingrasys/x86_64-ingrasys_s9200_64x-r0/led_proc_init.soc @@ -0,0 +1,111 @@ +#processor initialization for Ingrasys S9200-64X + +led 0 stop +led 0 prog 12 00 61 F1 12 10 61 F2 12 04 61 F3 12 04 61 F4 67 16 86 F0 77 74 96 F2 2E F1 67 2B 67 3F 16 F3 FE F1 61 F1 12 00 DE F2 74 16 57 2E F1 32 00 32 01 B7 97 75 3A 02 01 60 FE 57 02 00 60 FE 57 2E F1 32 08 97 75 58 77 48 06 FE D2 01 70 50 77 66 06 F0 C2 08 74 58 77 66 16 F4 91 22 0E 87 22 0E 87 DA 00 74 5A 57 16 F4 91 22 0F 87 22 0E 87 DA 00 74 68 57 02 80 38 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +modreg CMIC_LEDUP0_PORT_ORDER_REMAP_0_3 REMAP_PORT_3=56 REMAP_PORT_2=57 REMAP_PORT_1=58 REMAP_PORT_0=59 +modreg CMIC_LEDUP0_PORT_ORDER_REMAP_4_7 REMAP_PORT_7=60 REMAP_PORT_6=61 REMAP_PORT_5=62 REMAP_PORT_4=63 +modreg CMIC_LEDUP0_PORT_ORDER_REMAP_8_11 REMAP_PORT_11=52 REMAP_PORT_10=53 REMAP_PORT_9=54 REMAP_PORT_8=55 +modreg CMIC_LEDUP0_PORT_ORDER_REMAP_12_15 REMAP_PORT_15=48 REMAP_PORT_14=49 REMAP_PORT_13=50 REMAP_PORT_12=51 +modreg CMIC_LEDUP0_PORT_ORDER_REMAP_16_19 REMAP_PORT_19=40 REMAP_PORT_18=41 REMAP_PORT_17=42 REMAP_PORT_16=43 +modreg CMIC_LEDUP0_PORT_ORDER_REMAP_20_23 REMAP_PORT_23=44 REMAP_PORT_22=45 REMAP_PORT_21=46 REMAP_PORT_20=47 +modreg CMIC_LEDUP0_PORT_ORDER_REMAP_24_27 REMAP_PORT_27=36 REMAP_PORT_26=37 REMAP_PORT_25=38 REMAP_PORT_24=39 +modreg CMIC_LEDUP0_PORT_ORDER_REMAP_28_31 REMAP_PORT_31=32 REMAP_PORT_30=33 REMAP_PORT_29=34 REMAP_PORT_28=35 +modreg CMIC_LEDUP0_PORT_ORDER_REMAP_32_35 REMAP_PORT_35=24 REMAP_PORT_34=25 REMAP_PORT_33=26 REMAP_PORT_32=27 +modreg CMIC_LEDUP0_PORT_ORDER_REMAP_36_39 REMAP_PORT_39=28 REMAP_PORT_38=29 REMAP_PORT_37=30 REMAP_PORT_36=31 +modreg CMIC_LEDUP0_PORT_ORDER_REMAP_40_43 REMAP_PORT_43=20 REMAP_PORT_42=21 REMAP_PORT_41=22 REMAP_PORT_40=23 +modreg CMIC_LEDUP0_PORT_ORDER_REMAP_44_47 REMAP_PORT_47=16 REMAP_PORT_46=17 REMAP_PORT_45=18 REMAP_PORT_44=19 +modreg CMIC_LEDUP0_PORT_ORDER_REMAP_48_51 REMAP_PORT_51=8 REMAP_PORT_50=9 REMAP_PORT_49=10 REMAP_PORT_48=11 +modreg CMIC_LEDUP0_PORT_ORDER_REMAP_52_55 REMAP_PORT_55=12 REMAP_PORT_54=13 REMAP_PORT_53=14 REMAP_PORT_52=15 +modreg CMIC_LEDUP0_PORT_ORDER_REMAP_56_59 REMAP_PORT_59=4 REMAP_PORT_58=5 REMAP_PORT_57=6 REMAP_PORT_56=7 +modreg CMIC_LEDUP0_PORT_ORDER_REMAP_60_63 REMAP_PORT_63=0 REMAP_PORT_62=1 REMAP_PORT_61=2 REMAP_PORT_60=3 + +led 0 auto on +led 0 start + +led 1 stop +led 1 prog 12 00 61 F1 12 10 61 F2 12 04 61 F3 12 04 61 F4 67 16 86 F0 77 74 96 F2 2E F1 67 2B 67 3F 16 F3 FE F1 61 F1 12 00 DE F2 74 16 57 2E F1 32 00 32 01 B7 97 75 3A 02 01 60 FE 57 02 00 60 FE 57 2E F1 32 08 97 75 58 77 48 06 FE D2 01 70 50 77 66 06 F0 C2 08 74 58 77 66 16 F4 91 22 0E 87 22 0E 87 DA 00 74 5A 57 16 F4 91 22 0F 87 22 0E 87 DA 00 74 68 57 02 80 38 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +modreg CMIC_LEDUP1_PORT_ORDER_REMAP_0_3 REMAP_PORT_3=0 REMAP_PORT_2=1 REMAP_PORT_1=2 REMAP_PORT_0=3 +modreg CMIC_LEDUP1_PORT_ORDER_REMAP_4_7 REMAP_PORT_7=4 REMAP_PORT_6=5 REMAP_PORT_5=6 REMAP_PORT_4=7 +modreg CMIC_LEDUP1_PORT_ORDER_REMAP_8_11 REMAP_PORT_11=12 REMAP_PORT_10=13 REMAP_PORT_9=14 REMAP_PORT_8=15 +modreg CMIC_LEDUP1_PORT_ORDER_REMAP_12_15 REMAP_PORT_15=8 REMAP_PORT_14=9 REMAP_PORT_13=10 REMAP_PORT_12=11 +modreg CMIC_LEDUP1_PORT_ORDER_REMAP_16_19 REMAP_PORT_19=16 REMAP_PORT_18=17 REMAP_PORT_17=18 REMAP_PORT_16=19 +modreg CMIC_LEDUP1_PORT_ORDER_REMAP_20_23 REMAP_PORT_23=20 REMAP_PORT_22=21 REMAP_PORT_21=22 REMAP_PORT_20=23 +modreg CMIC_LEDUP1_PORT_ORDER_REMAP_24_27 REMAP_PORT_27=28 REMAP_PORT_26=29 REMAP_PORT_25=30 REMAP_PORT_24=31 +modreg CMIC_LEDUP1_PORT_ORDER_REMAP_28_31 REMAP_PORT_31=24 REMAP_PORT_30=25 REMAP_PORT_29=26 REMAP_PORT_28=27 +modreg CMIC_LEDUP1_PORT_ORDER_REMAP_32_35 REMAP_PORT_35=32 REMAP_PORT_34=33 REMAP_PORT_33=34 REMAP_PORT_32=35 +modreg CMIC_LEDUP1_PORT_ORDER_REMAP_36_39 REMAP_PORT_39=36 REMAP_PORT_38=37 REMAP_PORT_37=38 REMAP_PORT_36=39 +modreg CMIC_LEDUP1_PORT_ORDER_REMAP_40_43 REMAP_PORT_43=44 REMAP_PORT_42=45 REMAP_PORT_41=46 REMAP_PORT_40=47 +modreg CMIC_LEDUP1_PORT_ORDER_REMAP_44_47 REMAP_PORT_47=40 REMAP_PORT_46=41 REMAP_PORT_45=42 REMAP_PORT_44=43 +modreg CMIC_LEDUP1_PORT_ORDER_REMAP_48_51 REMAP_PORT_51=48 REMAP_PORT_50=49 REMAP_PORT_49=50 REMAP_PORT_48=51 +modreg CMIC_LEDUP1_PORT_ORDER_REMAP_52_55 REMAP_PORT_55=52 REMAP_PORT_54=53 REMAP_PORT_53=54 REMAP_PORT_52=55 +modreg CMIC_LEDUP1_PORT_ORDER_REMAP_56_59 REMAP_PORT_59=60 REMAP_PORT_58=61 REMAP_PORT_57=62 REMAP_PORT_56=63 +modreg CMIC_LEDUP1_PORT_ORDER_REMAP_60_63 REMAP_PORT_63=56 REMAP_PORT_62=57 REMAP_PORT_61=58 REMAP_PORT_60=59 + +led 1 auto on +led 1 start + +led 2 stop +led 2 prog 12 00 61 F1 12 10 61 F2 12 04 61 F3 12 04 61 F4 67 16 86 F0 77 74 96 F2 2E F1 67 2B 67 3F 16 F3 FE F1 61 F1 12 00 DE F2 74 16 57 2E F1 32 00 32 01 B7 97 75 3A 02 01 60 FE 57 02 00 60 FE 57 2E F1 32 08 97 75 58 77 48 06 FE D2 01 70 50 77 66 06 F0 C2 08 74 58 77 66 16 F4 91 22 0E 87 22 0E 87 DA 00 74 5A 57 16 F4 91 22 0F 87 22 0E 87 DA 00 74 68 57 02 80 38 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +modreg CMIC_LEDUP2_PORT_ORDER_REMAP_0_3 REMAP_PORT_3=56 REMAP_PORT_2=57 REMAP_PORT_1=58 REMAP_PORT_0=59 +modreg CMIC_LEDUP2_PORT_ORDER_REMAP_4_7 REMAP_PORT_7=60 REMAP_PORT_6=61 REMAP_PORT_5=62 REMAP_PORT_4=63 +modreg CMIC_LEDUP2_PORT_ORDER_REMAP_8_11 REMAP_PORT_11=52 REMAP_PORT_10=53 REMAP_PORT_9=54 REMAP_PORT_8=55 +modreg CMIC_LEDUP2_PORT_ORDER_REMAP_12_15 REMAP_PORT_15=48 REMAP_PORT_14=49 REMAP_PORT_13=50 REMAP_PORT_12=51 +modreg CMIC_LEDUP2_PORT_ORDER_REMAP_16_19 REMAP_PORT_19=40 REMAP_PORT_18=41 REMAP_PORT_17=42 REMAP_PORT_16=43 +modreg CMIC_LEDUP2_PORT_ORDER_REMAP_20_23 REMAP_PORT_23=44 REMAP_PORT_22=45 REMAP_PORT_21=46 REMAP_PORT_20=47 +modreg CMIC_LEDUP2_PORT_ORDER_REMAP_24_27 REMAP_PORT_27=36 REMAP_PORT_26=37 REMAP_PORT_25=38 REMAP_PORT_24=39 +modreg CMIC_LEDUP2_PORT_ORDER_REMAP_28_31 REMAP_PORT_31=32 REMAP_PORT_30=33 REMAP_PORT_29=34 REMAP_PORT_28=35 +modreg CMIC_LEDUP2_PORT_ORDER_REMAP_32_35 REMAP_PORT_35=24 REMAP_PORT_34=25 REMAP_PORT_33=26 REMAP_PORT_32=27 +modreg CMIC_LEDUP2_PORT_ORDER_REMAP_36_39 REMAP_PORT_39=28 REMAP_PORT_38=29 REMAP_PORT_37=30 REMAP_PORT_36=31 +modreg CMIC_LEDUP2_PORT_ORDER_REMAP_40_43 REMAP_PORT_43=20 REMAP_PORT_42=21 REMAP_PORT_41=22 REMAP_PORT_40=23 +modreg CMIC_LEDUP2_PORT_ORDER_REMAP_44_47 REMAP_PORT_47=16 REMAP_PORT_46=17 REMAP_PORT_45=18 REMAP_PORT_44=19 +modreg CMIC_LEDUP2_PORT_ORDER_REMAP_48_51 REMAP_PORT_51=8 REMAP_PORT_50=9 REMAP_PORT_49=10 REMAP_PORT_48=11 +modreg CMIC_LEDUP2_PORT_ORDER_REMAP_52_55 REMAP_PORT_55=12 REMAP_PORT_54=13 REMAP_PORT_53=14 REMAP_PORT_52=15 +modreg CMIC_LEDUP2_PORT_ORDER_REMAP_56_59 REMAP_PORT_59=4 REMAP_PORT_58=5 REMAP_PORT_57=6 REMAP_PORT_56=7 +modreg CMIC_LEDUP2_PORT_ORDER_REMAP_60_63 REMAP_PORT_63=0 REMAP_PORT_62=1 REMAP_PORT_61=2 REMAP_PORT_60=3 + +led 2 auto on +led 2 start + +led 3 stop +led 3 prog 12 00 61 F1 12 10 61 F2 12 04 61 F3 12 04 61 F4 67 16 86 F0 77 74 96 F2 2E F1 67 2B 67 3F 16 F3 FE F1 61 F1 12 00 DE F2 74 16 57 2E F1 32 00 32 01 B7 97 75 3A 02 01 60 FE 57 02 00 60 FE 57 2E F1 32 08 97 75 58 77 48 06 FE D2 01 70 50 77 66 06 F0 C2 08 74 58 77 66 16 F4 91 22 0E 87 22 0E 87 DA 00 74 5A 57 16 F4 91 22 0F 87 22 0E 87 DA 00 74 68 57 02 80 38 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +modreg CMIC_LEDUP3_PORT_ORDER_REMAP_0_3 REMAP_PORT_3=0 REMAP_PORT_2=1 REMAP_PORT_1=2 REMAP_PORT_0=3 +modreg CMIC_LEDUP3_PORT_ORDER_REMAP_4_7 REMAP_PORT_7=4 REMAP_PORT_6=5 REMAP_PORT_5=6 REMAP_PORT_4=7 +modreg CMIC_LEDUP3_PORT_ORDER_REMAP_8_11 REMAP_PORT_11=12 REMAP_PORT_10=13 REMAP_PORT_9=14 REMAP_PORT_8=15 +modreg CMIC_LEDUP3_PORT_ORDER_REMAP_12_15 REMAP_PORT_15=8 REMAP_PORT_14=9 REMAP_PORT_13=10 REMAP_PORT_12=11 +modreg CMIC_LEDUP3_PORT_ORDER_REMAP_16_19 REMAP_PORT_19=16 REMAP_PORT_18=17 REMAP_PORT_17=18 REMAP_PORT_16=19 +modreg CMIC_LEDUP3_PORT_ORDER_REMAP_20_23 REMAP_PORT_23=20 REMAP_PORT_22=21 REMAP_PORT_21=22 REMAP_PORT_20=23 +modreg CMIC_LEDUP3_PORT_ORDER_REMAP_24_27 REMAP_PORT_27=28 REMAP_PORT_26=29 REMAP_PORT_25=30 REMAP_PORT_24=31 +modreg CMIC_LEDUP3_PORT_ORDER_REMAP_28_31 REMAP_PORT_31=24 REMAP_PORT_30=25 REMAP_PORT_29=26 REMAP_PORT_28=27 +modreg CMIC_LEDUP3_PORT_ORDER_REMAP_32_35 REMAP_PORT_35=32 REMAP_PORT_34=33 REMAP_PORT_33=34 REMAP_PORT_32=35 +modreg CMIC_LEDUP3_PORT_ORDER_REMAP_36_39 REMAP_PORT_39=36 REMAP_PORT_38=37 REMAP_PORT_37=38 REMAP_PORT_36=39 +modreg CMIC_LEDUP3_PORT_ORDER_REMAP_40_43 REMAP_PORT_43=44 REMAP_PORT_42=45 REMAP_PORT_41=46 REMAP_PORT_40=47 +modreg CMIC_LEDUP3_PORT_ORDER_REMAP_44_47 REMAP_PORT_47=40 REMAP_PORT_46=41 REMAP_PORT_45=42 REMAP_PORT_44=43 +modreg CMIC_LEDUP3_PORT_ORDER_REMAP_48_51 REMAP_PORT_51=48 REMAP_PORT_50=49 REMAP_PORT_49=50 REMAP_PORT_48=51 +modreg CMIC_LEDUP3_PORT_ORDER_REMAP_52_55 REMAP_PORT_55=52 REMAP_PORT_54=53 REMAP_PORT_53=54 REMAP_PORT_52=55 +modreg CMIC_LEDUP3_PORT_ORDER_REMAP_56_59 REMAP_PORT_59=60 REMAP_PORT_58=61 REMAP_PORT_57=62 REMAP_PORT_56=63 +modreg CMIC_LEDUP3_PORT_ORDER_REMAP_60_63 REMAP_PORT_63=56 REMAP_PORT_62=57 REMAP_PORT_61=58 REMAP_PORT_60=59 + +led 3 auto on +led 3 start + +led 4 stop +led 4 prog 12 00 61 F1 12 40 61 F2 12 01 61 F3 12 01 61 F4 67 16 86 F0 77 74 96 F2 2E F1 67 2B 67 3F 16 F3 FE F1 61 F1 12 00 DE F2 74 16 57 2E F1 32 00 32 01 B7 97 75 3A 02 01 60 FE 57 02 00 60 FE 57 2E F1 32 08 97 75 58 77 48 06 FE D2 01 70 50 77 66 06 F0 C2 08 74 58 77 66 16 F4 91 22 0E 87 22 0E 87 DA 00 74 5A 57 16 F4 91 22 0F 87 22 0E 87 DA 00 74 68 57 02 80 38 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +modreg CMIC_LEDUP4_PORT_ORDER_REMAP_0_3 REMAP_PORT_3=62 REMAP_PORT_2=0 REMAP_PORT_1=63 REMAP_PORT_0=0 +modreg CMIC_LEDUP4_PORT_ORDER_REMAP_4_7 REMAP_PORT_7=0 REMAP_PORT_6=0 REMAP_PORT_5=0 REMAP_PORT_4=0 +modreg CMIC_LEDUP4_PORT_ORDER_REMAP_8_11 REMAP_PORT_11=0 REMAP_PORT_10=0 REMAP_PORT_9=0 REMAP_PORT_8=0 +modreg CMIC_LEDUP4_PORT_ORDER_REMAP_12_15 REMAP_PORT_15=0 REMAP_PORT_14=0 REMAP_PORT_13=0 REMAP_PORT_12=0 +modreg CMIC_LEDUP4_PORT_ORDER_REMAP_16_19 REMAP_PORT_19=0 REMAP_PORT_18=0 REMAP_PORT_17=0 REMAP_PORT_16=0 +modreg CMIC_LEDUP4_PORT_ORDER_REMAP_20_23 REMAP_PORT_23=0 REMAP_PORT_22=0 REMAP_PORT_21=0 REMAP_PORT_20=0 +modreg CMIC_LEDUP4_PORT_ORDER_REMAP_24_27 REMAP_PORT_27=0 REMAP_PORT_26=0 REMAP_PORT_25=0 REMAP_PORT_24=0 +modreg CMIC_LEDUP4_PORT_ORDER_REMAP_28_31 REMAP_PORT_31=0 REMAP_PORT_30=0 REMAP_PORT_29=0 REMAP_PORT_28=0 +modreg CMIC_LEDUP4_PORT_ORDER_REMAP_32_35 REMAP_PORT_35=0 REMAP_PORT_34=0 REMAP_PORT_33=0 REMAP_PORT_32=0 +modreg CMIC_LEDUP4_PORT_ORDER_REMAP_36_39 REMAP_PORT_39=0 REMAP_PORT_38=0 REMAP_PORT_37=0 REMAP_PORT_36=0 +modreg CMIC_LEDUP4_PORT_ORDER_REMAP_40_43 REMAP_PORT_43=0 REMAP_PORT_42=0 REMAP_PORT_41=0 REMAP_PORT_40=0 +modreg CMIC_LEDUP4_PORT_ORDER_REMAP_44_47 REMAP_PORT_47=0 REMAP_PORT_46=0 REMAP_PORT_45=0 REMAP_PORT_44=0 +modreg CMIC_LEDUP4_PORT_ORDER_REMAP_48_51 REMAP_PORT_51=0 REMAP_PORT_50=0 REMAP_PORT_49=0 REMAP_PORT_48=0 +modreg CMIC_LEDUP4_PORT_ORDER_REMAP_52_55 REMAP_PORT_55=0 REMAP_PORT_54=0 REMAP_PORT_53=0 REMAP_PORT_52=0 +modreg CMIC_LEDUP4_PORT_ORDER_REMAP_56_59 REMAP_PORT_59=0 REMAP_PORT_58=0 REMAP_PORT_57=0 REMAP_PORT_56=0 +modreg CMIC_LEDUP4_PORT_ORDER_REMAP_60_63 REMAP_PORT_63=0 REMAP_PORT_62=0 REMAP_PORT_61=0 REMAP_PORT_60=0 + +led 4 auto on +led 4 start diff --git a/device/ingrasys/x86_64-ingrasys_s9200_64x-r0/minigraph.xml b/device/ingrasys/x86_64-ingrasys_s9200_64x-r0/minigraph.xml new file mode 100644 index 000000000000..2b05e9ed15b7 --- /dev/null +++ b/device/ingrasys/x86_64-ingrasys_s9200_64x-r0/minigraph.xml @@ -0,0 +1,151 @@ + + + + + + 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 + + +
+
+ + + + + + HostIP + Loopback0 + + 100.0.0.9/32 + + 100.0.0.9/32 + + + + + + + + OCPSCH01040GGLF + + + + + + Ethernet0 + 10.10.1.25/30 + + + + Ethernet4 + 10.10.2.25/30 + + + + + + + + + + + + 40000 + DeviceInterfaceLink + OCPSCH0104001MS + Ethernet24 + OCPSCH01040GGLF + Ethernet0 + + + 40000 + DeviceInterfaceLink + OCPSCH0104002MS + Ethernet24 + OCPSCH01040GGLF + Ethernet4 + + + + + OCPSCH01040GGLF + INGRASYS-S9200-64X + + + + + + + OCPSCH01040GGLF + + + 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 + + + + + + + OCPSCH01040GGLF + INGRASYS-S9200-64X +
diff --git a/device/ingrasys/x86_64-ingrasys_s9200_64x-r0/plugins/eeprom.py b/device/ingrasys/x86_64-ingrasys_s9200_64x-r0/plugins/eeprom.py new file mode 100644 index 000000000000..3d01608ef7b2 --- /dev/null +++ b/device/ingrasys/x86_64-ingrasys_s9200_64x-r0/plugins/eeprom.py @@ -0,0 +1,24 @@ +#!/usr/bin/env python + +############################################################################# +# Ingrasys S9200-64X +# +# 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: + 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): + i2c_bus = "0" + i2c_addr = "0055" + self.eeprom_path = "/sys/class/i2c-adapter/i2c-" + i2c_bus + "/" + i2c_bus + "-" + i2c_addr + "/eeprom" + super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/ingrasys/x86_64-ingrasys_s9200_64x-r0/plugins/sfputil.py b/device/ingrasys/x86_64-ingrasys_s9200_64x-r0/plugins/sfputil.py new file mode 100644 index 000000000000..4d5651c63a68 --- /dev/null +++ b/device/ingrasys/x86_64-ingrasys_s9200_64x-r0/plugins/sfputil.py @@ -0,0 +1,260 @@ +# sfputil.py +# +# Platform-specific SFP transceiver interface for SONiC +# + +try: + import time + 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 = 63 + PORTS_IN_BLOCK = 64 + + EEPROM_OFFSET = 29 + + _port_to_eeprom_mapping = {} + + _logic_to_phy_port_mapping = { + 0: 0, + 1: 1, + 2: 4, + 3: 5, + 4: 8, + 5: 9, + 6: 12, + 7: 13, + 8: 16, + 9: 17, + 10: 20, + 11: 21, + 12: 24, + 13: 25, + 14: 28, + 15: 29, + 16: 32, + 17: 33, + 18: 36, + 19: 37, + 20: 40, + 21: 41, + 22: 44, + 23: 45, + 24: 48, + 25: 49, + 26: 52, + 27: 53, + 28: 56, + 29: 57, + 30: 60, + 31: 61, + 32: 2, + 33: 3, + 34: 6, + 35: 7, + 36: 10, + 37: 11, + 38: 14, + 39: 15, + 40: 18, + 41: 19, + 42: 22, + 43: 23, + 44: 26, + 45: 27, + 46: 30, + 47: 31, + 48: 34, + 49: 35, + 50: 38, + 51: 39, + 52: 42, + 53: 43, + 54: 46, + 55: 47, + 56: 50, + 57: 51, + 58: 54, + 59: 55, + 60: 58, + 61: 59, + 62: 62, + 63: 63 + } + + @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 = "/sys/class/i2c-adapter/i2c-{0}/{0}-0050/eeprom" + + for x in range(0, self.port_end + 1): + phy_port = self._logic_to_phy_port_mapping[x] + self._port_to_eeprom_mapping[x] = eeprom_path.format(phy_port + 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 + + # logic port to physical port mapping + port_num = self._logic_to_phy_port_mapping[port_num] + + try: + reg_file = open("/sys/devices/platform/ingrasys-s9200-cpld.0/qsfp_modprs") + 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) + + # Mask off the bit corresponding to our port + mask = (1 << port_num) + + # ModPrsL is active low + if reg_value & mask == 0: + 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 + + # logic port to physical port mapping + port_num = self._logic_to_phy_port_mapping[port_num] + + try: + reg_file = open("/sys/devices/platform/ingrasys-s9200-cpld.0/qsfp_lpmode") + except IOError as e: + print "Error: unable to open file: %s" % str(e) + + content = reg_file.readline().rstrip() + + # content is a string containing the hex representation of the register + reg_value = int(content, 16) + + # Mask off the bit corresponding to our port + mask = (1 << port_num) + + # LPMode is active high + if reg_value & mask == 0: + return False + + return True + + 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 + + # logic port to physical port mapping + port_num = self._logic_to_phy_port_mapping[port_num] + + try: + reg_file = open("/sys/devices/platform/ingrasys-s9200-cpld.0/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) + + # Mask off the bit corresponding to our port + mask = (1 << port_num) + + # 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 = format(reg_value, 'x') + + reg_file.seek(0) + reg_file.write(content) + reg_file.close() + + return True + + def reset(self, port_num): + QSFP_RESET_REGISTER_DEVICE_FILE = "/sys/devices/platform/ingrasys-s9200-cpld.0/qsfp_reset" + + # Check for invalid port_num + if port_num < self.port_start or port_num > self.port_end: + return False + + # logic port to physical port mapping + port_num = self._logic_to_phy_port_mapping[port_num] + + try: + reg_file = open(QSFP_RESET_REGISTER_DEVICE_FILE, "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) + + # Mask off the bit corresponding to our port + mask = (1 << port_num) + + # ResetL is active low + reg_value = reg_value & ~mask + + # Convert our register value back to a hex string and write back + content = format(reg_value, 'x') + + reg_file.seek(0) + reg_file.write(content) + 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(QSFP_RESET_REGISTER_DEVICE_FILE, "w") + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + reg_value = reg_value | mask + content = format(reg_value, 'x') + + reg_file.seek(0) + reg_file.write(content) + reg_file.close() + + return True diff --git a/device/ingrasys/x86_64-ingrasys_s9200_64x-r0/sensors.conf b/device/ingrasys/x86_64-ingrasys_s9200_64x-r0/sensors.conf new file mode 100644 index 000000000000..ef694e96a056 --- /dev/null +++ b/device/ingrasys/x86_64-ingrasys_s9200_64x-r0/sensors.conf @@ -0,0 +1,68 @@ +# libsensors configuration file +chip "i350bb-*" + ignore loc1 + +chip "jc42-*" + label temp1 "DIMM Temp" + set temp1_max 50 + set temp1_crit 85 + +chip "w83795adg-*" + ignore in0 + label in1 "P0V9" + set in1_min 0.90 * 0.97 + set in1_max 0.90 * 1.03 + ignore in2 + label in3 "P1V8" + set in3_min 1.8 * 0.97 + set in3_max 1.8 * 1.03 + label in4 "P1V0" + set in4_min 1.0 * 0.97 + set in4_max 1.0 * 1.03 + label in5 "P0V8" + set in5_min 0.8 * 0.97 + set in5_max 0.8 * 1.03 + ignore in6 + ignore in7 + ignore in8 + ignore in9 + ignore in10 + ignore in11 + ignore in12 + ignore in13 + ignore in14 + ignore in15 + ignore in16 + ignore in17 + ignore in18 + ignore in19 + label fan1 "FANTRAY 1" + ignore fan2 + label fan3 "FANTRAY 2" + ignore fan4 + label fan5 "FANTRAY 3" + ignore fan6 + label fan7 "FANTRAY 4" + ignore fan8 + ignore temp1 + ignore temp2 + ignore temp3 + ignore temp4 + ignore intrusion0 +bus "i2c-6" "i2c-0-mux (chan_id 5)" +chip "lm75-i2c-6-4E" + label temp1 "MAC Temp" + set temp1_max 50 + set temp1_max_hyst 45 + +bus "i2c-6" "i2c-0-mux (chan_id 5)" +chip "lm75-i2c-6-4D" + label temp1 "REAR Temp" + set temp1_max 50 + set temp1_max_hyst 45 + +bus "i2c-7" "i2c-0-mux (chan_id 6)" +chip "lm75-i2c-7-4D" + label temp1 "Front Temp" + set temp1_max 50 + set temp1_max_hyst 45 diff --git a/device/mellanox/x86_64-mlnx_msn2100-r0/plugins/psuutil.py b/device/mellanox/x86_64-mlnx_msn2100-r0/plugins/psuutil.py new file mode 100644 index 000000000000..88bdd51e9b67 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2100-r0/plugins/psuutil.py @@ -0,0 +1,64 @@ +#!/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 + """ + return isinstance(index, int) and index > 0 and index <= self.get_num_psus() diff --git a/device/mellanox/x86_64-mlnx_msn2410-r0/plugins/psuutil.py b/device/mellanox/x86_64-mlnx_msn2410-r0/plugins/psuutil.py new file mode 100644 index 000000000000..301569c13a94 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2410-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_msn2700-r0/ACS-MSN2700/qos.json b/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/qos.json new file mode 100644 index 000000000000..3e01af3f2c64 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/qos.json @@ -0,0 +1,166 @@ +{ + "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", + "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", + "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_msn2700-r0/Mellanox-SN2700 b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700 new file mode 120000 index 000000000000..9f12504c7c5a --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700 @@ -0,0 +1 @@ +ACS-MSN2700 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/psuutil.py b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/psuutil.py new file mode 100644 index 000000000000..301569c13a94 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2700-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_msn2740-r0/ACS-MSN2740/qos.json b/device/mellanox/x86_64-mlnx_msn2740-r0/ACS-MSN2740/qos.json new file mode 120000 index 000000000000..ae738e606a9d --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2740-r0/ACS-MSN2740/qos.json @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/ACS-MSN2700/qos.json \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn2740-r0/plugins/psuutil.py b/device/mellanox/x86_64-mlnx_msn2740-r0/plugins/psuutil.py new file mode 100644 index 000000000000..301569c13a94 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2740-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/dockers/docker-database/Dockerfile.j2 b/dockers/docker-database/Dockerfile.j2 index 19fd412b0387..7fb3401184f2 100644 --- a/dockers/docker-database/Dockerfile.j2 +++ b/dockers/docker-database/Dockerfile.j2 @@ -33,6 +33,6 @@ RUN sed -ri 's/^(save .*$)/# \1/g; ' /etc/redis/redis.conf COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] -COPY ["configdb-load.sh", "/usr/bin/"] +COPY ["files/configdb-load.sh", "/usr/bin/"] ENTRYPOINT ["/usr/bin/supervisord"] diff --git a/dockers/docker-dhcp-relay/start.sh b/dockers/docker-dhcp-relay/start.sh index b53d7e4e238a..2ee80c4e3388 100755 --- a/dockers/docker-dhcp-relay/start.sh +++ b/dockers/docker-dhcp-relay/start.sh @@ -6,7 +6,12 @@ rm -f /var/run/rsyslogd.pid # Start rsyslog supervisorctl start rsyslogd -# Wait for all interfaces to come up before starting the DHCP relay agent(s) +# 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) diff --git a/dockers/docker-dhcp-relay/wait_for_intf.sh.j2 b/dockers/docker-dhcp-relay/wait_for_intf.sh.j2 index 1524b3221312..037dc66ead63 100644 --- a/dockers/docker-dhcp-relay/wait_for_intf.sh.j2 +++ b/dockers/docker-dhcp-relay/wait_for_intf.sh.j2 @@ -1,27 +1,42 @@ #!/usr/bin/env bash -function wait_until_iface_exists +function wait_until_iface_ready { IFACE=$1 - echo "Waiting for interface ${IFACE}..." + echo "Waiting until interface $IFACE is up..." # Wait for the interface to come up (i.e., 'ip link show' returns 0) - until ip link show $IFACE > /dev/null 2>&1; do + until ip link show dev $IFACE up > /dev/null 2>&1; do sleep 1 done - echo "Interface ${IFACE} is created" + echo "Interface $IFACE is up" + + echo "Waiting until interface $IFACE has an IPv4 address..." + + # Wait until the interface gets assigned an IPv4 address + while true; do + IP=$(ip -4 addr show dev $IFACE | grep "inet " | awk '{ print $2 }' | cut -d '/' -f1) + + if [ -n "$IP" ]; then + break + fi + + sleep 1 + done + + echo "Interface $IFACE is configured with IP $IP" } -# Wait for all interfaces to come up before starting the DHCP relay +# Wait for all interfaces to come up and have IPv4 addresses assigned {% for (name, prefix) in INTERFACE %} -wait_until_iface_exists {{ name }} +wait_until_iface_ready {{ name }} {% endfor %} {% for (name, prefix) in VLAN_INTERFACE %} -wait_until_iface_exists {{ name }} +wait_until_iface_ready {{ name }} {% endfor %} {% for (name, prefix) in PORTCHANNEL_INTERFACE %} -wait_until_iface_exists {{ name }} +wait_until_iface_ready {{ name }} {% endfor %} diff --git a/dockers/docker-fpm-frr/bgpd.conf.j2 b/dockers/docker-fpm-frr/bgpd.conf.j2 index 07e2dd0c571e..9afd6a5a8bf0 100644 --- a/dockers/docker-fpm-frr/bgpd.conf.j2 +++ b/dockers/docker-fpm-frr/bgpd.conf.j2 @@ -23,8 +23,13 @@ router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} bgp bestpath as-path multipath-relax no bgp default ipv4-unicast {# TODO: use lo[0] for backward compatibility, will revisit the case with multiple lo interfaces #} - bgp router-id {{ LOOPBACK_INTERFACE.keys()[0][1] }} +{% for (name, prefix) in LOOPBACK_INTERFACE %} +{% if prefix | ipv4 and name == 'Loopback0' %} + bgp router-id {{ prefix | ip }} +{% endif %} +{% endfor %} {# advertise loopback #} + {% for (name, prefix) in LOOPBACK_INTERFACE %} {% if prefix | ipv4 %} network {{ prefix | ip }}/32 diff --git a/dockers/docker-fpm-quagga/start.sh b/dockers/docker-fpm-quagga/start.sh index 1e7a49809d55..06fdd3bb3961 100755 --- a/dockers/docker-fpm-quagga/start.sh +++ b/dockers/docker-fpm-quagga/start.sh @@ -1,15 +1,15 @@ #!/usr/bin/env bash mkdir -p /etc/quagga -sonic-cfggen -m -d -y /etc/sonic/deployment_id_asn_map.yml -t /usr/share/sonic/templates/bgpd.conf.j2 > /etc/quagga/bgpd.conf +sonic-cfggen -d -y /etc/sonic/deployment_id_asn_map.yml -t /usr/share/sonic/templates/bgpd.conf.j2 > /etc/quagga/bgpd.conf -sonic-cfggen -m -d -t /usr/share/sonic/templates/zebra.conf.j2 > /etc/quagga/zebra.conf +sonic-cfggen -d -t /usr/share/sonic/templates/zebra.conf.j2 > /etc/quagga/zebra.conf -sonic-cfggen -m -d -t /usr/share/sonic/templates/isolate.j2 > /usr/sbin/bgp-isolate +sonic-cfggen -d -t /usr/share/sonic/templates/isolate.j2 > /usr/sbin/bgp-isolate chown root:root /usr/sbin/bgp-isolate chmod 0755 /usr/sbin/bgp-isolate -sonic-cfggen -m -d -t /usr/share/sonic/templates/unisolate.j2 > /usr/sbin/bgp-unisolate +sonic-cfggen -d -t /usr/share/sonic/templates/unisolate.j2 > /usr/sbin/bgp-unisolate chown root:root /usr/sbin/bgp-unisolate chmod 0755 /usr/sbin/bgp-unisolate diff --git a/dockers/docker-lldp-sv2/lldpd.conf.j2 b/dockers/docker-lldp-sv2/lldpd.conf.j2 index eb7202df7c67..165ded79f392 100644 --- a/dockers/docker-lldp-sv2/lldpd.conf.j2 +++ b/dockers/docker-lldp-sv2/lldpd.conf.j2 @@ -1,3 +1,4 @@ +configure ports eth0 lldp portidsubtype local {{ MGMT_INTERFACE.keys()[0][0] }} {% 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-orchagent/Dockerfile.j2 b/dockers/docker-orchagent/Dockerfile.j2 index 9fba8d17b9d6..3d6671996358 100755 --- a/dockers/docker-orchagent/Dockerfile.j2 +++ b/dockers/docker-orchagent/Dockerfile.j2 @@ -26,7 +26,8 @@ debs/{{ deb }}{{' '}} RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y RUN rm -rf /debs -COPY ["arp_update", "start.sh", "orchagent.sh", "swssconfig.sh", "/usr/bin/"] +COPY ["files/arp_update", "/usr/bin"] +COPY ["start.sh", "orchagent.sh", "swssconfig.sh", "/usr/bin/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] ## Copy all Jinja2 template files into the templates folder diff --git a/dockers/docker-orchagent/msn27xx.32ports.buffers.json.j2 b/dockers/docker-orchagent/msn27xx.32ports.buffers.json.j2 index ce1ddedbba37..0a60f4584a19 100644 --- a/dockers/docker-orchagent/msn27xx.32ports.buffers.json.j2 +++ b/dockers/docker-orchagent/msn27xx.32ports.buffers.json.j2 @@ -32,7 +32,7 @@ "BUFFER_PROFILE_TABLE:ingress_lossless_profile": { "pool":"[BUFFER_POOL_TABLE:ingress_lossless_pool]", "size":"0", - "dynamic_th":"7" + "dynamic_th":"1" }, "OP": "SET" }, @@ -47,7 +47,7 @@ { "BUFFER_PROFILE_TABLE:egress_lossless_profile": { "pool":"[BUFFER_POOL_TABLE:egress_lossless_pool]", - "size":"1518", + "size":"0", "dynamic_th":"7" }, "OP": "SET" @@ -64,7 +64,7 @@ "BUFFER_PROFILE_TABLE:pg_lossy_profile": { "pool":"[BUFFER_POOL_TABLE:ingress_lossy_pool]", "size":"0", - "dynamic_th":"3" + "dynamic_th":"7" }, "OP": "SET" }, @@ -80,7 +80,7 @@ "BUFFER_PROFILE_TABLE:q_lossy_profile": { "pool":"[BUFFER_POOL_TABLE:egress_lossy_pool]", "size":"0", - "dynamic_th":"1" + "dynamic_th":"7" }, "OP": "SET" }, diff --git a/dockers/docker-orchagent/ports.json.j2 b/dockers/docker-orchagent/ports.json.j2 index 48be831025f8..e0438998114d 100644 --- a/dockers/docker-orchagent/ports.json.j2 +++ b/dockers/docker-orchagent/ports.json.j2 @@ -4,7 +4,8 @@ {% if PORT[port].has_key('speed') %} { "PORT_TABLE:{{ port }}": { - "speed": "{{ PORT[port]['speed'] }}" + "speed": "{{ PORT[port]['speed'] }}", + "description": "{{ PORT[port]['description'] }}" }, "OP": "SET" }{% if not loop.last %},{% endif %} diff --git a/dockers/docker-orchagent/start.sh b/dockers/docker-orchagent/start.sh index 9f3ba3cb078d..dfdb5b897bbb 100755 --- a/dockers/docker-orchagent/start.sh +++ b/dockers/docker-orchagent/start.sh @@ -2,9 +2,9 @@ mkdir -p /etc/swss/config.d/ -sonic-cfggen -m /etc/sonic/minigraph.xml -d -t /usr/share/sonic/templates/switch.json.j2 > /etc/swss/config.d/switch.json -sonic-cfggen -m /etc/sonic/minigraph.xml -d -t /usr/share/sonic/templates/ipinip.json.j2 > /etc/swss/config.d/ipinip.json -sonic-cfggen -m /etc/sonic/minigraph.xml -d -t /usr/share/sonic/templates/ports.json.j2 > /etc/swss/config.d/ports.json +sonic-cfggen -d -t /usr/share/sonic/templates/switch.json.j2 > /etc/swss/config.d/switch.json +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 export platform=`sonic-cfggen -v platform` diff --git a/dockers/docker-orchagent/swssconfig.sh b/dockers/docker-orchagent/swssconfig.sh index aee3ffaaa8cb..c8ee8759333c 100755 --- a/dockers/docker-orchagent/swssconfig.sh +++ b/dockers/docker-orchagent/swssconfig.sh @@ -25,7 +25,7 @@ function fast_reboot { # Restore FDB and ARP table ASAP fast_reboot -HWSKU=`sonic-cfggen -m /etc/sonic/minigraph.xml -d -v "DEVICE_METADATA['localhost']['hwsku']"` +HWSKU=`sonic-cfggen -d -v "DEVICE_METADATA['localhost']['hwsku']"` SWSSCONFIG_ARGS="00-copp.config.json ipinip.json ports.json switch.json " @@ -38,8 +38,8 @@ elif [ "$HWSKU" == "Force10-S6100" ]; then elif [ "$HWSKU" == "Arista-7050-QX32" ]; then SWSSCONFIG_ARGS+="td2.32ports.buffers.json td2.32ports.qos.json " elif [[ "$HWSKU" == "ACS-MSN27"* ]]; then - sonic-cfggen -m /etc/sonic/minigraph.xml -t /usr/share/sonic/templates/msn27xx.32ports.buffers.json.j2 > /etc/swss/config.d/msn27xx.32ports.buffers.json - SWSSCONFIG_ARGS+="msn27xx.32ports.buffers.json msn27xx.32ports.qos.json " + sonic-cfggen -d -t /usr/share/sonic/templates/msn27xx.32ports.buffers.json.j2 > /etc/swss/config.d/msn27xx.32ports.buffers.json + SWSSCONFIG_ARGS+="msn27xx.32ports.buffers.json " fi for file in $SWSSCONFIG_ARGS; do diff --git a/dockers/docker-ptf/Dockerfile.j2 b/dockers/docker-ptf/Dockerfile.j2 index 01312687b93c..2d9b1544d95a 100644 --- a/dockers/docker-ptf/Dockerfile.j2 +++ b/dockers/docker-ptf/Dockerfile.j2 @@ -100,6 +100,10 @@ RUN mkdir /var/run/sshd \ COPY ["supervisord.conf", "/etc/supervisor/"] COPY ["conf.d/supervisord.conf", "conf.d/sshd.conf", "conf.d/ptf_nn_agent.conf", "/etc/supervisor/conf.d/"] +# Move tcpdump into /usr/bin Otherwise it's impossible to run tcpdump due to a docker bug +RUN mv /usr/sbin/tcpdump /usr/bin/tcpdump +RUN ln -s /usr/bin/tcpdump /usr/sbin/tcpdump + RUN mkdir -p /var/log/supervisor EXPOSE 22 diff --git a/dockers/docker-snmp-sv2/Dockerfile.j2 b/dockers/docker-snmp-sv2/Dockerfile.j2 index 2ab867031874..3c5473951116 100644 --- a/dockers/docker-snmp-sv2/Dockerfile.j2 +++ b/dockers/docker-snmp-sv2/Dockerfile.j2 @@ -7,6 +7,7 @@ COPY [ \ "/debs/"] # Install Python SwSSSDK (SNMP subagent dependency) +COPY python-wheels/sonic_utilities-*-py3-*.whl /python-wheels/ COPY python-wheels/swsssdk-*-py3-*.whl /python-wheels/ COPY python-wheels/asyncsnmp-*-py3-*.whl /python-wheels/ diff --git a/files/Aboot/boot0.j2 b/files/Aboot/boot0.j2 index 18d1ee126c00..a2c683b20c91 100644 --- a/files/Aboot/boot0.j2 +++ b/files/Aboot/boot0.j2 @@ -110,30 +110,37 @@ platform_specific() { # set varlog size to 100MB local varlog_size=100 - # This is temporary as the platform= and sid= parameters don't provide enough - # information to identify the SKU - # An initramfs hook or a later processing done by the initscripts will be - # required to read the system eeprom + local flash_size=$(($(df | grep flash | tr -s ' ' | cut -f2 -d' ') / 1000)) + if [ "$platform" = "raven" ]; then aboot_machine=arista_7050_qx32 + flash_size=2000 echo "modprobe.blacklist=radeon" >>/tmp/append fi if [ "$platform" = "crow" ]; then aboot_machine=arista_7050_qx32s + flash_size=3700 echo "modprobe.blacklist=radeon" >>/tmp/append fi if [ "$sid" = "Upperlake" ] || [ "$sid" = "UpperlakeES" ]; then aboot_machine=arista_7060_cx32s + flash_size=3700 echo "amd_iommu=off" >> /tmp/append fi if [ "$sid" = "Gardena" ] || [ "$sid" = "GardenaSsd" ]; then aboot_machine=arista_7260cx3_64 + flash_size=28000 fi if [ "$platform" = "rook" ]; then - varlog_size=4096 readprefdl -f /tmp/.system-prefdl -d > /mnt/flash/.system-prefdl fi + if [ $flash_size -ge 28000 ]; then + varlog_size=4096 + elif [ $flash_size -ge 3700 ]; then + varlog_size=400 + fi + echo "varlog_size=$varlog_size" >>/tmp/append } diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 37fcfbc56fcb..fd67444fb475 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -89,6 +89,14 @@ sudo cp -f $IMAGE_CONFIGS/bash/bash.bashrc $FILESYSTEM_ROOT/etc/ sudo dpkg --root=$FILESYSTEM_ROOT -i target/debs/sonic-device-data_*.deb || \ sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f +# Install pam-tacplus and nss-tacplus +sudo dpkg --root=$FILESYSTEM_ROOT -i target/debs/libtac2_*.deb +sudo dpkg --root=$FILESYSTEM_ROOT -i target/debs/libpam-tacplus_*.deb +sudo dpkg --root=$FILESYSTEM_ROOT -i target/debs/libnss-tacplus_*.deb +# Disable tacplus by default +sudo LANG=C chroot $FILESYSTEM_ROOT pam-auth-update --remove tacplus +sudo sed -i -e '/^passwd/s/ tacplus//' $FILESYSTEM_ROOT/etc/nsswitch.conf + # Copy crontabs sudo cp -f $IMAGE_CONFIGS/cron.d/* $FILESYSTEM_ROOT/etc/cron.d/ @@ -120,6 +128,11 @@ sudo cp $IMAGE_CONFIGS/interfaces/*.j2 $FILESYSTEM_ROOT/usr/share/sonic/template # Copy initial interfaces configuration file, will be overwritten on first boot sudo cp $IMAGE_CONFIGS/interfaces/init_interfaces $FILESYSTEM_ROOT/etc/network +# Copy hostname configuration scripts +sudo cp $IMAGE_CONFIGS/hostname/hostname-config.service $FILESYSTEM_ROOT/etc/systemd/system/ +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/ sudo LANG=C chroot $FILESYSTEM_ROOT systemctl enable updategraph.service diff --git a/files/image_config/hostname/hostname-config.service b/files/image_config/hostname/hostname-config.service new file mode 100644 index 000000000000..e6e8f489883f --- /dev/null +++ b/files/image_config/hostname/hostname-config.service @@ -0,0 +1,11 @@ +[Unit] +Description=Update hostname based on configdb +Requires=database.service +After=database.service + +[Service] +Type=oneshot +ExecStart=/usr/bin/hostname-config.sh + +[Install] +WantedBy=multi-user.target diff --git a/files/image_config/hostname/hostname-config.sh b/files/image_config/hostname/hostname-config.sh new file mode 100755 index 000000000000..eec7c2f732dc --- /dev/null +++ b/files/image_config/hostname/hostname-config.sh @@ -0,0 +1,11 @@ +#!/bin/bash -e + +CURRENT_HOSTNAME=`hostname` +HOSTNAME=`sonic-cfggen -d -v DEVICE_METADATA[\'localhost\'][\'hostname\']` + +echo $HOSTNAME > /etc/hostname +hostname -F /etc/hostname + +sed -i "/\s$CURRENT_HOSTNAME$/d" /etc/hosts +echo "127.0.0.1 $HOSTNAME" >> /etc/hosts + diff --git a/files/image_config/platform/rc.local b/files/image_config/platform/rc.local index c7915db9eb7c..436a7de9071e 100755 --- a/files/image_config/platform/rc.local +++ b/files/image_config/platform/rc.local @@ -112,6 +112,12 @@ if [ -f /host/image-$sonic_version/platform/firsttime ]; then else # Use default minigraph.xml cp /usr/share/sonic/device/$platform/minigraph.xml /etc/sonic/ + HWSKU=`sonic-cfggen -m /etc/sonic/minigraph.xml -v "DEVICE_METADATA['localhost']['hwsku']"` + if [ -f /usr/share/sonic/device/$platform/$HWSKU/qos.json ]; then + # merge qos configuration into init config file + sonic-cfggen -j /etc/sonic/init_cfg.json -j /usr/share/sonic/device/$platform/$HWSKU/qos.json --print-data > /tmp/init_cfg.json + mv /tmp/init_cfg.json /etc/sonic/init_cfg.json + fi sonic-cfggen -m -j /etc/sonic/init_cfg.json --print-data > /etc/sonic/config_db.json fi diff --git a/files/image_config/updategraph/updategraph.service b/files/image_config/updategraph/updategraph.service index c66e9be75702..0162754ab2db 100644 --- a/files/image_config/updategraph/updategraph.service +++ b/files/image_config/updategraph/updategraph.service @@ -1,5 +1,6 @@ [Unit] Description=download minigraph from graph service +After=rc-local.service Before=database.service [Service] diff --git a/files/initramfs-tools/arista-convertfs.j2 b/files/initramfs-tools/arista-convertfs.j2 index cea25bd39837..dfd2fc1d7407 100644 --- a/files/initramfs-tools/arista-convertfs.j2 +++ b/files/initramfs-tools/arista-convertfs.j2 @@ -87,6 +87,9 @@ fixup_flash_permissions() { # this allows the sonic admin user to have read access on the flash local flash_mnt="$1" chmod o+rx "$flash_mnt" + + # remove all the filesystem acls from the flash + setfacl -Rb "$flash_mnt" } # Extract kernel parameters diff --git a/files/initramfs-tools/setfacl b/files/initramfs-tools/setfacl new file mode 100644 index 000000000000..96564e06b245 --- /dev/null +++ b/files/initramfs-tools/setfacl @@ -0,0 +1,20 @@ +#!/bin/sh +#Part of the code is revised based on initramfs-tools/hooks/fsck and initramfs-tool is under GPL v2. + +PREREQ="" + +prereqs() +{ + echo "$PREREQ" +} + +case $1 in +prereqs) + prereqs + exit 0 + ;; +esac + +. /usr/share/initramfs-tools/hook-functions + +copy_exec /usr/bin/setfacl /sbin/setfacl diff --git a/dockers/docker-orchagent/arp_update b/files/scripts/arp_update similarity index 100% rename from dockers/docker-orchagent/arp_update rename to files/scripts/arp_update diff --git a/dockers/docker-database/configdb-load.sh b/files/scripts/configdb-load.sh similarity index 100% rename from dockers/docker-database/configdb-load.sh rename to files/scripts/configdb-load.sh diff --git a/platform/barefoot/docker-orchagent-bfn.mk b/platform/barefoot/docker-orchagent-bfn.mk index ac338f2ba7e6..f13fa63d6f2a 100644 --- a/platform/barefoot/docker-orchagent-bfn.mk +++ b/platform/barefoot/docker-orchagent-bfn.mk @@ -16,3 +16,4 @@ $(DOCKER_ORCHAGENT_BFN)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro $(DOCKER_ORCHAGENT_BFN)_RUN_OPT += -v /var/log/swss:/var/log/swss:rw $(DOCKER_ORCHAGENT_BFN)_BASE_IMAGE_FILES += swssloglevel:/usr/bin/swssloglevel +$(DOCKER_ORCHAGENT_BFN)_FILES += $(ARP_UPDATE_SCRIPT) diff --git a/platform/broadcom/docker-orchagent-brcm.mk b/platform/broadcom/docker-orchagent-brcm.mk index 196a4d589a24..066973967450 100644 --- a/platform/broadcom/docker-orchagent-brcm.mk +++ b/platform/broadcom/docker-orchagent-brcm.mk @@ -16,3 +16,4 @@ $(DOCKER_ORCHAGENT_BRCM)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro $(DOCKER_ORCHAGENT_BRCM)_RUN_OPT += -v /var/log/swss:/var/log/swss:rw $(DOCKER_ORCHAGENT_BRCM)_BASE_IMAGE_FILES += swssloglevel:/usr/bin/swssloglevel +$(DOCKER_ORCHAGENT_BRCM)_FILES += $(ARP_UPDATE_SCRIPT) diff --git a/platform/broadcom/one-image.mk b/platform/broadcom/one-image.mk old mode 100644 new mode 100755 index ca9da1134eb2..5b2afedee7d7 --- a/platform/broadcom/one-image.mk +++ b/platform/broadcom/one-image.mk @@ -11,9 +11,12 @@ $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(DELL_S6000_PLATFORM_MODULE) \ $(INGRASYS_S8900_64XC_PLATFORM_MODULE) \ $(INGRASYS_S9100_PLATFORM_MODULE) \ $(INGRASYS_S8810_32Q_PLATFORM_MODULE) \ + $(INGRASYS_S9200_64X_PLATFORM_MODULE) \ $(ACCTON_AS7712_32X_PLATFORM_MODULE) \ + $(ACCTON_AS5712_54X_PLATFORM_MODULE) \ $(INVENTEC_D7032Q28B_PLATFORM_MODULE) \ $(INVENTEC_D7054Q28B_PLATFORM_MODULE) \ - $(CEL_DX010_PLATFORM_MODULE) + $(CEL_DX010_PLATFORM_MODULE) \ + $(DELTA_AG9032V1_PLATFORM_MODULE) $(SONIC_ONE_IMAGE)_DOCKERS += $(SONIC_INSTALL_DOCKER_IMAGES) SONIC_INSTALLERS += $(SONIC_ONE_IMAGE) diff --git a/platform/broadcom/platform-modules-accton.mk b/platform/broadcom/platform-modules-accton.mk old mode 100644 new mode 100755 index e5357c5e9f14..6a2bf8c04b6f --- a/platform/broadcom/platform-modules-accton.mk +++ b/platform/broadcom/platform-modules-accton.mk @@ -1,11 +1,19 @@ # Accton Platform modules -ACCTON_AS7712_32X_PLATFORM_MODULE_VERSION = 1.0 +ACCTON_AS7712_32X_PLATFORM_MODULE_VERSION = 1.1 +ACCTON_AS5712_54X_PLATFORM_MODULE_VERSION = 1.1 export ACCTON_AS7712_32X_PLATFORM_MODULE_VERSION +export ACCTON_AS5712_54X_PLATFORM_MODULE_VERSION ACCTON_AS7712_32X_PLATFORM_MODULE = sonic-platform-accton-as7712-32x_$(ACCTON_AS7712_32X_PLATFORM_MODULE_VERSION)_amd64.deb $(ACCTON_AS7712_32X_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-accton $(ACCTON_AS7712_32X_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) $(ACCTON_AS7712_32X_PLATFORM_MODULE)_PLATFORM = x86_64-accton_as7712_32x-r0 SONIC_DPKG_DEBS += $(ACCTON_AS7712_32X_PLATFORM_MODULE) + +ACCTON_AS5712_54X_PLATFORM_MODULE = sonic-platform-accton-as5712-54x_$(ACCTON_AS5712_54X_PLATFORM_MODULE_VERSION)_amd64.deb +$(ACCTON_AS5712_54X_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-accton +$(ACCTON_AS5712_54X_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) +$(ACCTON_AS5712_54X_PLATFORM_MODULE)_PLATFORM = x86_64-accton_as5712_54x-r0 +SONIC_DPKG_DEBS += $(ACCTON_AS5712_54X_PLATFORM_MODULE) diff --git a/platform/broadcom/platform-modules-delta.mk b/platform/broadcom/platform-modules-delta.mk new file mode 100644 index 000000000000..c73b128106a9 --- /dev/null +++ b/platform/broadcom/platform-modules-delta.mk @@ -0,0 +1,12 @@ +# Delta AG9032v1 Platform modules + +DELTA_AG9032V1_PLATFORM_MODULE_VERSION = 1.1 + +export DELTA_AG9032V1_PLATFORM_MODULE_VERSION + +DELTA_AG9032V1_PLATFORM_MODULE = platform-modules-ag9032v1_$(DELTA_AG9032V1_PLATFORM_MODULE_VERSION)_amd64.deb +$(DELTA_AG9032V1_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-delta +$(DELTA_AG9032V1_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) +$(DELTA_AG9032V1_PLATFORM_MODULE)_PLATFORM = x86_64-delta_ag9032v1-r0 +SONIC_DPKG_DEBS += $(DELTA_AG9032V1_PLATFORM_MODULE) + diff --git a/platform/broadcom/platform-modules-ingrasys.mk b/platform/broadcom/platform-modules-ingrasys.mk index e5ef4021eff7..f402a7fed1c6 100644 --- a/platform/broadcom/platform-modules-ingrasys.mk +++ b/platform/broadcom/platform-modules-ingrasys.mk @@ -4,11 +4,13 @@ INGRASYS_S9100_PLATFORM_MODULE_VERSION = 1.1.0 INGRASYS_S8900_64XC_PLATFORM_MODULE_VERSION = 1.1.0 INGRASYS_S8900_54XC_PLATFORM_MODULE_VERSION = 1.1.0 INGRASYS_S8810_32Q_PLATFORM_MODULE_VERSION = 1.1.0 +INGRASYS_S9200_64X_PLATFORM_MODULE_VERSION = 1.1.0 export INGRASYS_S9100_PLATFORM_MODULE_VERSION export INGRASYS_S8900_64XC_PLATFORM_MODULE_VERSION export INGRASYS_S8900_54XC_PLATFORM_MODULE_VERSION export INGRASYS_S8810_32Q_PLATFORM_MODULE_VERSION +export INGRASYS_S9200_64X_PLATFORM_MODULE_VERSION INGRASYS_S9100_PLATFORM_MODULE = sonic-platform-ingrasys-s9100_$(INGRASYS_S9100_PLATFORM_MODULE_VERSION)_amd64.deb $(INGRASYS_S9100_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-ingrasys @@ -25,6 +27,10 @@ $(INGRASYS_S8900_54XC_PLATFORM_MODULE)_PLATFORM = x86_64-ingrasys_s8900_54xc-r0 INGRASYS_S8810_32Q_PLATFORM_MODULE = sonic-platform-ingrasys-s8810-32q_$(INGRASYS_S8810_32Q_PLATFORM_MODULE_VERSION)_amd64.deb $(INGRASYS_S8810_32Q_PLATFORM_MODULE)_PLATFORM = x86_64-ingrasys_s8810_32q-r0 +INGRASYS_S9200_64X_PLATFORM_MODULE = sonic-platform-ingrasys-s9200-64x_$(INGRASYS_S9200_64X_PLATFORM_MODULE_VERSION)_amd64.deb +$(INGRASYS_S9200_64X_PLATFORM_MODULE)_PLATFORM = x86_64-ingrasys_s9200_64x-r0 + $(eval $(call add_extra_package,$(INGRASYS_S9100_PLATFORM_MODULE),$(INGRASYS_S8900_64XC_PLATFORM_MODULE))) $(eval $(call add_extra_package,$(INGRASYS_S9100_PLATFORM_MODULE),$(INGRASYS_S8900_54XC_PLATFORM_MODULE))) $(eval $(call add_extra_package,$(INGRASYS_S9100_PLATFORM_MODULE),$(INGRASYS_S8810_32Q_PLATFORM_MODULE))) +$(eval $(call add_extra_package,$(INGRASYS_S9100_PLATFORM_MODULE),$(INGRASYS_S9200_64X_PLATFORM_MODULE))) diff --git a/platform/broadcom/rules.mk b/platform/broadcom/rules.mk index b52118570251..e94361987963 100755 --- a/platform/broadcom/rules.mk +++ b/platform/broadcom/rules.mk @@ -7,6 +7,7 @@ include $(PLATFORM_PATH)/platform-modules-ingrasys.mk include $(PLATFORM_PATH)/platform-modules-accton.mk include $(PLATFORM_PATH)/platform-modules-inventec.mk include $(PLATFORM_PATH)/platform-modules-cel.mk +include $(PLATFORM_PATH)/platform-modules-delta.mk include $(PLATFORM_PATH)/docker-orchagent-brcm.mk include $(PLATFORM_PATH)/docker-syncd-brcm.mk include $(PLATFORM_PATH)/docker-syncd-brcm-rpc.mk diff --git a/platform/broadcom/sai.mk b/platform/broadcom/sai.mk index 376882d95825..6b1795f87ecc 100644 --- a/platform/broadcom/sai.mk +++ b/platform/broadcom/sai.mk @@ -1,9 +1,9 @@ -BRCM_SAI = libsaibcm_3.0.3.2-13_amd64.deb -$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/libsaibcm_3.0.3.2-13_amd64.deb?sv=2015-04-05&sr=b&sig=YeXV0av6rUxy3s5VlQf4wsv6dLOKIGkkkP8lldlGr00%3D&se=2031-07-27T07%3A49%3A38Z&sp=r" +BRCM_SAI = libsaibcm_3.0.3.3_amd64.deb +$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/libsaibcm_3.0.3.3_amd64.deb?sv=2015-04-05&sr=b&sig=itlsEt8vqhWfZzuq%2FOSWSGgHN5kokf5a9AYOSJhD3t4%3D&se=2031-08-16T03%3A11%3A13Z&sp=r" -BRCM_SAI_DEV = libsaibcm-dev_3.0.3.2-13_amd64.deb +BRCM_SAI_DEV = libsaibcm-dev_3.0.3.3_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.0.3.2-13_amd64.deb?sv=2015-04-05&sr=b&sig=u4dKbtc%2FAvlqq7l7BT9WcmLVEsWoV1LqOxSbBy0CkiA%3D&se=2031-07-27T07%3A50%3A08Z&sp=r" +$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/libsaibcm-dev_3.0.3.3_amd64.deb?sv=2015-04-05&sr=b&sig=0DXLHgPXuMHERp44qJNNdQyYSv969sQsY7USCL6gCRw%3D&se=2031-08-16T03%3A10%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 aff0cf07fe5c..dbabf8aaba15 100644 --- a/platform/broadcom/sdk.mk +++ b/platform/broadcom/sdk.mk @@ -1,4 +1,4 @@ -BRCM_OPENNSL_KERNEL = opennsl-modules-3.16.0-4-amd64_3.2.3.3-2_amd64.deb -$(BRCM_OPENNSL_KERNEL)_URL = "https://sonicstorage.blob.core.windows.net/packages/opennsl-modules-3.16.0-4-amd64_3.2.3.3-2_amd64.deb?sv=2015-04-05&sr=b&sig=RADtBDA9oZmwHnTzBY76ewajyJ8Af%2BchVCzNbe%2BPsbc%3D&se=2031-07-06T19%3A18%3A56Z&sp=r" +BRCM_OPENNSL_KERNEL = opennsl-modules-3.16.0-4-amd64_3.2.3.7-1_amd64.deb +$(BRCM_OPENNSL_KERNEL)_URL = "https://sonicstorage.blob.core.windows.net/packages/opennsl-modules-3.16.0-4-amd64_3.2.3.7-1_amd64.deb?sv=2015-04-05&sr=b&sig=BJEFXfq2mgvSTIYZF8qF1Jj2ePkJaxBmA0HqhhAFPmQ%3D&se=2031-08-11T03%3A27%3A43Z&sp=r" SONIC_ONLINE_DEBS += $(BRCM_OPENNSL_KERNEL) diff --git a/platform/broadcom/sonic-platform-modules-accton b/platform/broadcom/sonic-platform-modules-accton index 99607d63220d..edfb5b2c1285 160000 --- a/platform/broadcom/sonic-platform-modules-accton +++ b/platform/broadcom/sonic-platform-modules-accton @@ -1 +1 @@ -Subproject commit 99607d63220de336a61d81f6b4d1e64062761abe +Subproject commit edfb5b2c1285cbfd30d8a662ab738aee53a80439 diff --git a/platform/broadcom/sonic-platform-modules-arista b/platform/broadcom/sonic-platform-modules-arista index f985b188326e..8b8411551faa 160000 --- a/platform/broadcom/sonic-platform-modules-arista +++ b/platform/broadcom/sonic-platform-modules-arista @@ -1 +1 @@ -Subproject commit f985b188326e480124ec49541b4fecc51a213889 +Subproject commit 8b8411551faab9e44aa1f66dae507e3d92ecf468 diff --git a/platform/broadcom/sonic-platform-modules-delta/LICENSE b/platform/broadcom/sonic-platform-modules-delta/LICENSE new file mode 100644 index 000000000000..ea87fe9caabe --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-delta/LICENSE @@ -0,0 +1,16 @@ +Copyright (C) 2016 Microsoft, Inc +Copyright (C) 2017 Delta 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 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-delta/ag9032v1/cfg/ag9032v1-modules.conf b/platform/broadcom/sonic-platform-modules-delta/ag9032v1/cfg/ag9032v1-modules.conf new file mode 100644 index 000000000000..552b4103ed02 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-delta/ag9032v1/cfg/ag9032v1-modules.conf @@ -0,0 +1,13 @@ +# /etc/modules: kernel modules to load at boot time. +# +# This file contains the names of kernel modules that should be loaded +# at boot time, one per line. Lines beginning with "#" are ignored. + +i2c-i801 +i2c-isch +i2c-ismt +i2c-dev +i2c-mux +i2c-smbus +i2c-mux-gpio +i2c-mux-pca954x diff --git a/platform/broadcom/sonic-platform-modules-delta/ag9032v1/modules/Makefile b/platform/broadcom/sonic-platform-modules-delta/ag9032v1/modules/Makefile new file mode 100644 index 000000000000..69b3b48885d3 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-delta/ag9032v1/modules/Makefile @@ -0,0 +1,2 @@ +obj-m := at24.o dni_ag9032v1_psu.o dni_emc2305.o delta_ag9032v1_platform.o + diff --git a/platform/broadcom/sonic-platform-modules-delta/ag9032v1/modules/at24.c b/platform/broadcom/sonic-platform-modules-delta/ag9032v1/modules/at24.c new file mode 100644 index 000000000000..8e73691647d8 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-delta/ag9032v1/modules/at24.c @@ -0,0 +1,698 @@ +/* + * at24.c - handle most I2C EEPROMs + * + * Copyright (C) 2005-2007 David Brownell + * Copyright (C) 2008 Wolfram Sang, Pengutronix + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * I2C EEPROMs from most vendors are inexpensive and mostly interchangeable. + * Differences between different vendor product lines (like Atmel AT24C or + * MicroChip 24LC, etc) won't much matter for typical read/write access. + * There are also I2C RAM chips, likewise interchangeable. One example + * would be the PCF8570, which acts like a 24c02 EEPROM (256 bytes). + * + * However, misconfiguration can lose data. "Set 16-bit memory address" + * to a part with 8-bit addressing will overwrite data. Writing with too + * big a page size also loses data. And it's not safe to assume that the + * conventional addresses 0x50..0x57 only hold eeproms; a PCF8563 RTC + * uses 0x51, for just one example. + * + * Accordingly, explicit board-specific configuration data should be used + * in almost all cases. (One partial exception is an SMBus used to access + * "SPD" data for DRAM sticks. Those only use 24c02 EEPROMs.) + * + * So this driver uses "new style" I2C driver binding, expecting to be + * told what devices exist. That may be in arch/X/mach-Y/board-Z.c or + * similar kernel-resident tables; or, configuration data coming from + * a bootloader. + * + * Other than binding model, current differences from "eeprom" driver are + * that this one handles write access and isn't restricted to 24c02 devices. + * It also handles larger devices (32 kbit and up) with two-byte addresses, + * which won't work on pure SMBus systems. + */ + +struct at24_data { + struct at24_platform_data chip; + struct memory_accessor macc; + int use_smbus; + + /* + * Lock protects against activities from other Linux tasks, + * but not from changes by other I2C masters. + */ + struct mutex lock; + struct bin_attribute bin; + + u8 *writebuf; + unsigned write_max; + unsigned num_addresses; + + /* + * Some chips tie up multiple I2C addresses; dummy devices reserve + * them for us, and we'll use them with SMBus calls. + */ + struct i2c_client *client[]; +}; + +/* + * 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 = 32; +module_param(io_limit, uint, 0); +MODULE_PARM_DESC(io_limit, "Maximum bytes per I/O (default 32)"); + +/* + * 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; +module_param(write_timeout, uint, 0); +MODULE_PARM_DESC(write_timeout, "Time (in ms) to try writes (default 25)"); + +#define AT24_SIZE_BYTELEN 5 +#define AT24_SIZE_FLAGS 8 + +#define AT24_BITMASK(x) (BIT(x) - 1) + +/* create non-zero magic value for given eeprom parameters */ +#define AT24_DEVICE_MAGIC(_len, _flags) \ + ((1 << AT24_SIZE_FLAGS | (_flags)) \ + << AT24_SIZE_BYTELEN | ilog2(_len)) + +static const struct i2c_device_id at24_ids[] = { + /* needs 8 addresses as A0-A2 are ignored */ + { "24c00", AT24_DEVICE_MAGIC(128 / 8, AT24_FLAG_TAKE8ADDR) }, + /* old variants can't be handled with this generic entry! */ + { "24c01", AT24_DEVICE_MAGIC(1024 / 8, 0) }, + { "24c02", AT24_DEVICE_MAGIC(2048 / 8, 0) }, + /* spd is a 24c02 in memory DIMMs */ + { "spd", AT24_DEVICE_MAGIC(2048 / 8, + AT24_FLAG_READONLY | AT24_FLAG_IRUGO) }, + { "24c04", AT24_DEVICE_MAGIC(4096 / 8, 0) }, + /* 24rf08 quirk is handled at i2c-core */ + { "24c08", AT24_DEVICE_MAGIC(8192 / 8, 0) }, + { "24c16", AT24_DEVICE_MAGIC(16384 / 8, 0) }, + { "24c32", AT24_DEVICE_MAGIC(32768 / 8, AT24_FLAG_ADDR16) }, + { "24c64", AT24_DEVICE_MAGIC(65536 / 8, AT24_FLAG_ADDR16) }, + { "24c128", AT24_DEVICE_MAGIC(131072 / 8, AT24_FLAG_ADDR16) }, + { "24c256", AT24_DEVICE_MAGIC(262144 / 8, AT24_FLAG_ADDR16) }, + { "24c512", AT24_DEVICE_MAGIC(524288 / 8, AT24_FLAG_ADDR16) }, + { "24c1024", AT24_DEVICE_MAGIC(1048576 / 8, AT24_FLAG_ADDR16) }, + { "at24", 0 }, + { /* END OF LIST */ } +}; +MODULE_DEVICE_TABLE(i2c, at24_ids); + +/*-------------------------------------------------------------------------*/ + +/* + * This routine supports chips which consume multiple I2C addresses. It + * computes the addressing information to be used for a given r/w request. + * Assumes that sanity checks for offset happened at sysfs-layer. + */ +static struct i2c_client *at24_translate_offset(struct at24_data *at24, + unsigned *offset) +{ + unsigned i; + + if (at24->chip.flags & AT24_FLAG_ADDR16) { + i = *offset >> 16; + *offset &= 0xffff; + } else { + i = *offset >> 8; + *offset &= 0xff; + } + + return at24->client[i]; +} + +static ssize_t at24_eeprom_read(struct at24_data *at24, char *buf, + unsigned offset, size_t count) +{ + struct i2c_msg msg[2]; + u8 msgbuf[2]; + struct i2c_client *client; + unsigned long timeout, read_time; + int status, i; + + memset(msg, 0, sizeof(msg)); + + /* + * REVISIT some multi-address chips don't rollover page reads to + * the next slave address, so we may need to truncate the count. + * Those chips might need another quirk flag. + * + * If the real hardware used four adjacent 24c02 chips and that + * were misconfigured as one 24c08, that would be a similar effect: + * one "eeprom" file not four, but larger reads would fail when + * they crossed certain pages. + */ + + /* + * Slave address and byte offset derive from the offset. Always + * set the byte address; on a multi-master board, another master + * may have changed the chip's "current" address pointer. + */ + client = at24_translate_offset(at24, &offset); + + if (count > io_limit) + count = io_limit; + + switch (at24->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. Note that read page rollover helps us + * here (unlike writes). msgbuf is u8 and will cast to our + * needs. + */ + i = 0; + if (at24->chip.flags & AT24_FLAG_ADDR16) + msgbuf[i++] = offset >> 8; + 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 (at24->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, "read %zu@%d --> %d (%ld)\n", + count, offset, status, jiffies); + + if (status == count) + return count; + + /* REVISIT: at HZ=100, this is sloooow */ + msleep(1); + } while (time_before(read_time, timeout)); + + return -ETIMEDOUT; +} + +static ssize_t at24_read(struct at24_data *at24, + char *buf, loff_t off, size_t count) +{ + ssize_t retval = 0; + + if (unlikely(!count)) + return count; + + /* + * Read data from chip, protecting against concurrent updates + * from this host, but not from other I2C masters. + */ + mutex_lock(&at24->lock); + + while (count) { + ssize_t status; + + status = at24_eeprom_read(at24, buf, off, count); + if (status <= 0) { + if (retval == 0) + retval = status; + break; + } + buf += status; + off += status; + count -= status; + retval += status; + } + + mutex_unlock(&at24->lock); + + return retval; +} + +static ssize_t at24_bin_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, + char *buf, loff_t off, size_t count) +{ + struct at24_data *at24; + + at24 = dev_get_drvdata(container_of(kobj, struct device, kobj)); + return at24_read(at24, buf, off, count); +} + + +/* + * Note that if the hardware write-protect pin is pulled high, the whole + * chip is normally write protected. But there are plenty of product + * variants here, including OTP fuses and partial chip protect. + * + * We only use page mode writes; the alternative is sloooow. This routine + * writes at most one page. + */ +static ssize_t at24_eeprom_write(struct at24_data *at24, const char *buf, + unsigned offset, size_t count) +{ + struct i2c_client *client; + struct i2c_msg msg; + ssize_t status; + unsigned long timeout, write_time; + unsigned next_page; + + /* Get corresponding I2C address and adjust offset */ + client = at24_translate_offset(at24, &offset); + + /* write_max is at most a page */ + if (count > at24->write_max) + count = at24->write_max; + + /* Never roll over backwards, to the start of this page */ + next_page = roundup(offset + 1, at24->chip.page_size); + if (offset + count > next_page) + count = next_page - offset; + + /* If we'll use I2C calls for I/O, set up the message */ + if (!at24->use_smbus) { + int i = 0; + + msg.addr = client->addr; + msg.flags = 0; + + /* msg.buf is u8 and casts will mask the values */ + msg.buf = at24->writebuf; + if (at24->chip.flags & AT24_FLAG_ADDR16) + msg.buf[i++] = offset >> 8; + + msg.buf[i++] = offset; + memcpy(&msg.buf[i], buf, count); + msg.len = i + count; + } + + /* + * Writes fail if the previous one 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; + if (at24->use_smbus) { + status = i2c_smbus_write_i2c_block_data(client, + offset, count, buf); + if (status == 0) + status = count; + } else { + status = i2c_transfer(client->adapter, &msg, 1); + if (status == 1) + status = count; + } + dev_dbg(&client->dev, "write %zu@%d --> %zd (%ld)\n", + count, offset, 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 at24_write(struct at24_data *at24, 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(&at24->lock); + + while (count) { + ssize_t status; + + status = at24_eeprom_write(at24, buf, off, count); + if (status <= 0) { + if (retval == 0) + retval = status; + break; + } + buf += status; + off += status; + count -= status; + retval += status; + } + + mutex_unlock(&at24->lock); + + return retval; +} + +static ssize_t at24_bin_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, + char *buf, loff_t off, size_t count) +{ + struct at24_data *at24; + + if (unlikely(off >= attr->size)) + return -EFBIG; + + at24 = dev_get_drvdata(container_of(kobj, struct device, kobj)); + return at24_write(at24, buf, off, count); +} + +/*-------------------------------------------------------------------------*/ + +/* + * This lets other kernel code access the eeprom data. For example, it + * might hold a board's Ethernet address, or board-specific calibration + * data generated on the manufacturing floor. + */ + +static ssize_t at24_macc_read(struct memory_accessor *macc, char *buf, + off_t offset, size_t count) +{ + struct at24_data *at24 = container_of(macc, struct at24_data, macc); + + return at24_read(at24, buf, offset, count); +} + +static ssize_t at24_macc_write(struct memory_accessor *macc, const char *buf, + off_t offset, size_t count) +{ + struct at24_data *at24 = container_of(macc, struct at24_data, macc); + + return at24_write(at24, buf, offset, count); +} + +/*-------------------------------------------------------------------------*/ + +#ifdef CONFIG_OF +static void at24_get_ofdata(struct i2c_client *client, + struct at24_platform_data *chip) +{ + const __be32 *val; + struct device_node *node = client->dev.of_node; + + if (node) { + if (of_get_property(node, "read-only", NULL)) + chip->flags |= AT24_FLAG_READONLY; + val = of_get_property(node, "pagesize", NULL); + if (val) + chip->page_size = be32_to_cpup(val); + } +} +#else +static void at24_get_ofdata(struct i2c_client *client, + struct at24_platform_data *chip) +{ } +#endif /* CONFIG_OF */ + +static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id) +{ + struct at24_platform_data chip; + bool writable; + int use_smbus = 0; + struct at24_data *at24; + int err; + unsigned i, num_addresses; + kernel_ulong_t magic; + + if (client->dev.platform_data) { + chip = *(struct at24_platform_data *)client->dev.platform_data; + } else { + if (!id->driver_data) + return -ENODEV; + + magic = id->driver_data; + chip.byte_len = BIT(magic & AT24_BITMASK(AT24_SIZE_BYTELEN)); + magic >>= AT24_SIZE_BYTELEN; + chip.flags = magic & AT24_BITMASK(AT24_SIZE_FLAGS); + /* + * This is slow, but we can't know all eeproms, so we better + * play safe. Specifying custom eeprom-types via platform_data + * is recommended anyhow. + */ + chip.page_size = 1; + + /* update chipdata if OF is present */ + at24_get_ofdata(client, &chip); + + chip.setup = NULL; + chip.context = NULL; + } + + if (!is_power_of_2(chip.byte_len)) + dev_warn(&client->dev, + "byte_len looks suspicious (no power of 2)!\n"); + if (!chip.page_size) { + dev_err(&client->dev, "page_size must not be 0!\n"); + return -EINVAL; + } + if (!is_power_of_2(chip.page_size)) + dev_warn(&client->dev, + "page_size looks suspicious (no power of 2)!\n"); + + /* Use I2C operations unless we're stuck with SMBus extensions. */ + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { + if (chip.flags & AT24_FLAG_ADDR16) + return -EPFNOSUPPORT; + + if (i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_READ_I2C_BLOCK)) { + use_smbus = I2C_SMBUS_I2C_BLOCK_DATA; + } else if (i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_READ_WORD_DATA)) { + use_smbus = I2C_SMBUS_WORD_DATA; + } else if (i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_READ_BYTE_DATA)) { + use_smbus = I2C_SMBUS_BYTE_DATA; + } else { + return -EPFNOSUPPORT; + } + } + + if (chip.flags & AT24_FLAG_TAKE8ADDR) + num_addresses = 8; + else + num_addresses = DIV_ROUND_UP(chip.byte_len, + (chip.flags & AT24_FLAG_ADDR16) ? 65536 : 256); + + at24 = devm_kzalloc(&client->dev, sizeof(struct at24_data) + + num_addresses * sizeof(struct i2c_client *), GFP_KERNEL); + if (!at24) + return -ENOMEM; + + mutex_init(&at24->lock); + at24->use_smbus = use_smbus; + at24->chip = chip; + at24->num_addresses = num_addresses; + + /* + * Export the EEPROM bytes through sysfs, since that's convenient. + * By default, only root should see the data (maybe passwords etc) + */ + sysfs_bin_attr_init(&at24->bin); + at24->bin.attr.name = "eeprom"; + at24->bin.attr.mode = chip.flags & AT24_FLAG_IRUGO ? S_IRUGO : S_IRUSR; + at24->bin.read = at24_bin_read; + at24->bin.size = chip.byte_len; + + at24->macc.read = at24_macc_read; + + writable = !(chip.flags & AT24_FLAG_READONLY); + if (writable) { + if (!use_smbus || i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_WRITE_I2C_BLOCK)) { + + unsigned write_max = chip.page_size; + + at24->macc.write = at24_macc_write; + + at24->bin.write = at24_bin_write; + at24->bin.attr.mode |= S_IWUSR; + + if (write_max > io_limit) + write_max = io_limit; + if (use_smbus && write_max > I2C_SMBUS_BLOCK_MAX) + write_max = I2C_SMBUS_BLOCK_MAX; + at24->write_max = write_max; + + /* buffer (data + address at the beginning) */ + at24->writebuf = devm_kzalloc(&client->dev, + write_max + 2, GFP_KERNEL); + if (!at24->writebuf) + return -ENOMEM; + } else { + dev_warn(&client->dev, + "cannot write due to controller restrictions."); + } + } + + at24->client[0] = client; + + /* use dummy devices for multiple-address chips */ + for (i = 1; i < num_addresses; i++) { + at24->client[i] = i2c_new_dummy(client->adapter, + client->addr + i); + if (!at24->client[i]) { + dev_err(&client->dev, "address 0x%02x unavailable\n", + client->addr + i); + err = -EADDRINUSE; + goto err_clients; + } + } + + err = sysfs_create_bin_file(&client->dev.kobj, &at24->bin); + if (err) + goto err_clients; + + i2c_set_clientdata(client, at24); + + dev_info(&client->dev, "%zu byte %s EEPROM, %s, %u bytes/write\n", + at24->bin.size, client->name, + writable ? "writable" : "read-only", at24->write_max); + if (use_smbus == I2C_SMBUS_WORD_DATA || + use_smbus == I2C_SMBUS_BYTE_DATA) { + dev_notice(&client->dev, "Falling back to %s reads, " + "performance will suffer\n", use_smbus == + I2C_SMBUS_WORD_DATA ? "word" : "byte"); + } + + /* export data to kernel code */ + if (chip.setup) + chip.setup(&at24->macc, chip.context); + + return 0; + +err_clients: + for (i = 1; i < num_addresses; i++) + if (at24->client[i]) + i2c_unregister_device(at24->client[i]); + + return err; +} + +static int at24_remove(struct i2c_client *client) +{ + struct at24_data *at24; + int i; + + at24 = i2c_get_clientdata(client); + sysfs_remove_bin_file(&client->dev.kobj, &at24->bin); + + for (i = 1; i < at24->num_addresses; i++) + i2c_unregister_device(at24->client[i]); + + return 0; +} + +/*-------------------------------------------------------------------------*/ + +static struct i2c_driver at24_driver = { + .driver = { + .name = "at24", + .owner = THIS_MODULE, + }, + .probe = at24_probe, + .remove = at24_remove, + .id_table = at24_ids, +}; + +static int __init at24_init(void) +{ + if (!io_limit) { + pr_err("at24: io_limit must not be 0!\n"); + return -EINVAL; + } + + io_limit = rounddown_pow_of_two(io_limit); + return i2c_add_driver(&at24_driver); +} +module_init(at24_init); + +static void __exit at24_exit(void) +{ + i2c_del_driver(&at24_driver); +} +module_exit(at24_exit); + +MODULE_DESCRIPTION("Driver for most I2C EEPROMs"); +MODULE_AUTHOR("David Brownell and Wolfram Sang"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-delta/ag9032v1/modules/delta_ag9032v1_platform.c b/platform/broadcom/sonic-platform-modules-delta/ag9032v1/modules/delta_ag9032v1_platform.c new file mode 100644 index 000000000000..90454a5bdb4a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-delta/ag9032v1/modules/delta_ag9032v1_platform.c @@ -0,0 +1,1530 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define BUS3_DEV_NUM 9 +#define BUS4_DEV_NUM 6 +#define BUS5_DEV_NUM 32 +#define DEFAULT_NUM 1 +#define BUS3_BASE_NUM 30 +#define BUS4_BASE_NUM 40 +#define BUS5_BASE_NUM 50 + +#define BUS3_MUX_REG 0x21 +#define BUS4_MUX_REG 0x21 +#define BUS5_MUX_REG 0x20 + +#define TEMP_FAN_VAL 0x06 +#define FANIO_CTL_VAL 0x07 +#define FAN_CTRL_VAL 0x05 +#define PSU1_VAL 0x00 +#define PSU2_VAL 0x20 +#define HOT_SWAP1_VAL 0x10 +#define HOT_SWAP2_VAL 0x30 +#define FAN_EEPROM1_VAL 0x00 +#define FAN_EEPROM2_VAL 0x01 +#define FAN_EEPROM3_VAL 0x02 +#define FAN_EEPROM4_VAL 0x03 +#define FAN_EEPROM5_VAL 0x04 + +#define SWPLD_REG 0x31 +#define SWPLD_SFP_MUX_REG 0x20 + +#define SYS_LED_REG 0x1C +#define FAN1_LED_REG 0x1D +#define FAN2_LED_REG 0x1E + +#define SFP_PRESENCE_1 0x38 +#define SFP_PRESENCE_2 0x39 +#define SFP_PRESENCE_3 0x3A +#define SFP_PRESENCE_4 0x3B + +#define SFP_LP_MODE_1 0x34 +#define SFP_LP_MODE_2 0x35 +#define SFP_LP_MODE_3 0x36 +#define SFP_LP_MODE_4 0x37 + +#define SFP_RESET_1 0x3C +#define SFP_RESET_2 0x3D +#define SFP_RESET_3 0x3E +#define SFP_RESET_4 0x3F + +#define SFP_RESPONSE_1 0x30 +#define SFP_RESPONSE_2 0x31 +#define SFP_RESPONSE_3 0x32 +#define SFP_RESPONSE_4 0x33 + +#define SFF8436_INFO(data) \ + .type = "sff8436", .addr = 0x50, .platform_data = (data) + +#define SFF_8346_PORT(eedata) \ + .byte_len = 256, .page_size = 1, .flags = SFF_8436_FLAG_READONLY + +#define ag9032v1_i2c_device_num(NUM){ \ + .name = "delta-ag9032v1-i2c-device", \ + .id = NUM, \ + .dev = { \ + .platform_data = &ag9032v1_i2c_device_platform_data[NUM], \ + .release = device_release, \ + }, \ +} + +/*Define struct to get client of i2c_new_deivce */ +struct i2c_client * i2c_client_9547; + +enum{ + BUS0 = 0, + BUS1, + BUS2, + BUS3, + BUS4, + BUS5, + BUS6, + BUS7, +}; + +unsigned char reverse_8bits(unsigned char c) +{ + unsigned char s = 0; + int i; + for (i = 0; i < 8; ++i) { + s <<= 1; + s |= c & 1; + c >>= 1; + } + return s; +} +/*---------------- I2C device - start ------------- */ +static void device_release(struct device *dev) +{ + return; +} + +struct i2c_device_platform_data { + int parent; + struct i2c_board_info info; + struct i2c_client *client; +}; +/* pca9547 - add 8 bus */ +static struct pca954x_platform_mode pca954x_mode[] = { + { .adap_id = 2, + .deselect_on_exit = 1, + }, + { .adap_id = 3, + .deselect_on_exit = 1, + }, + { .adap_id = 4, + .deselect_on_exit = 1, + }, + { .adap_id = 5, + .deselect_on_exit = 1, + }, + { .adap_id = 6, + .deselect_on_exit = 1, + }, + { .adap_id = 7, + .deselect_on_exit = 1, + }, + { .adap_id = 8, + .deselect_on_exit = 1, + }, + { .adap_id = 9, + .deselect_on_exit = 1, + }, +}; + +static struct pca954x_platform_data pca954x_data = { + .modes = pca954x_mode, + .num_modes = ARRAY_SIZE(pca954x_mode), +}; + +static struct i2c_board_info __initdata i2c_info_pca9547[] = +{ + { + I2C_BOARD_INFO("pca9547", 0x71), + .platform_data = &pca954x_data, + }, +}; + + +static struct sff_8436_platform_data sff_8436_port[] = { + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, + { SFF_8346_PORT() }, +}; + +static struct i2c_device_platform_data ag9032v1_i2c_device_platform_data[] = { + { + /* tmp75 (0x4d) */ + .parent = 2, + .info = { I2C_BOARD_INFO("tmp75", 0x4d) }, + .client = NULL, + }, + { + /* id eeprom (0x53) */ + .parent = 2, + .info = { I2C_BOARD_INFO("24c02", 0x53) }, + .client = NULL, + }, + { + /* tmp75 (0x4c) */ + .parent = 7, + .info = { I2C_BOARD_INFO("tmp75", 0x4c) }, + .client = NULL, + }, + { + /* tmp75 (0x4d) */ + .parent = 7, + .info = { I2C_BOARD_INFO("tmp75", 0x4d) }, + .client = NULL, + }, + { + /* tmp75 (0x4e) */ + .parent = 7, + .info = { I2C_BOARD_INFO("tmp75", 0x4e) }, + .client = NULL, + }, + { + /* tmp75 (0x4f) */ + .parent = 30, + .info = { I2C_BOARD_INFO("tmp75", 0x4f) }, + .client = NULL, + }, + { + /* FAN 1 Controller (0x2c) */ + .parent = 37, + .info = { I2C_BOARD_INFO("emc2305", 0x2c) }, + .client = NULL, + }, + { + /* FAN 2 Controller (0x2d) */ + .parent = 38, + .info = { I2C_BOARD_INFO("emc2305", 0x2d) }, + .client = NULL, + }, + { + /* psu 1 (0x58) */ + .parent = 40, + .info = { .type = "dni_ag9032v1_psu", .addr = 0x58, .platform_data = 0 }, + .client = NULL, + }, + { + /* psu 2 (0x58) */ + .parent = 41, + .info = { .type = "dni_ag9032v1_psu", .addr = 0x58, .platform_data = 1 }, + .client = NULL, + }, + { + /* hot-swap 1 (0x40) */ + .parent = 42, + .info = { .type = "ltc4215", .addr = 0x40, .platform_data = 0 }, + .client = NULL, + }, + { + /* hot-swap 2 (0x40) */ + .parent = 43, + .info = { .type = "ltc4215", .addr = 0x40, .platform_data = 1 }, + .client = NULL, + }, + { + /* qsfp 1 (0x50) */ + .parent = 50, + .info = { SFF8436_INFO(&sff_8436_port[0]) }, + .client = NULL, + }, + { + /* qsfp 2 (0x50) */ + .parent = 51, + .info = { SFF8436_INFO(&sff_8436_port[1]) }, + .client = NULL, + }, + { + /* qsfp 3 (0x50) */ + .parent = 52, + .info = { SFF8436_INFO(&sff_8436_port[2]) }, + .client = NULL, + }, + { + /* qsfp 4 (0x50) */ + .parent = 53, + .info = { SFF8436_INFO(&sff_8436_port[3]) }, + .client = NULL, + }, + { + /* qsfp 5 (0x50) */ + .parent = 54, + .info = { SFF8436_INFO(&sff_8436_port[4]) }, + .client = NULL, + }, + { + /* qsfp 6 (0x50) */ + .parent = 55, + .info = { SFF8436_INFO(&sff_8436_port[5]) }, + .client = NULL, + }, + { + /* qsfp 7 (0x50) */ + .parent = 56, + .info = { SFF8436_INFO(&sff_8436_port[6]) }, + .client = NULL, + }, + { + /* qsfp 8 (0x50) */ + .parent = 57, + .info = { SFF8436_INFO(&sff_8436_port[7]) }, + .client = NULL, + }, + { + /* qsfp 9 (0x50) */ + .parent = 58, + .info = { SFF8436_INFO(&sff_8436_port[8]) }, + .client = NULL, + }, + { + /* qsfp 10 (0x50) */ + .parent = 59, + .info = { SFF8436_INFO(&sff_8436_port[9]) }, + .client = NULL, + }, + { + /* qsfp 11 (0x50) */ + .parent = 60, + .info = { SFF8436_INFO(&sff_8436_port[10]) }, + .client = NULL, + }, + { + /* qsfp 12 (0x50) */ + .parent = 61, + .info = { SFF8436_INFO(&sff_8436_port[11]) }, + .client = NULL, + }, + { + /* qsfp 13 (0x50) */ + .parent = 62, + .info = { SFF8436_INFO(&sff_8436_port[12]) }, + .client = NULL, + }, + { + /* qsfp 14 (0x50) */ + .parent = 63, + .info = { SFF8436_INFO(&sff_8436_port[13]) }, + .client = NULL, + }, + { + /* qsfp 15 (0x50) */ + .parent = 64, + .info = { SFF8436_INFO(&sff_8436_port[14]) }, + .client = NULL, + }, + { + /* qsfp 16 (0x50) */ + .parent = 65, + .info = { SFF8436_INFO(&sff_8436_port[15]) }, + .client = NULL, + }, + { + /* qsfp 17 (0x50) */ + .parent = 66, + .info = { SFF8436_INFO(&sff_8436_port[16]) }, + .client = NULL, + }, + { + /* qsfp 18 (0x50) */ + .parent = 67, + .info = { SFF8436_INFO(&sff_8436_port[17]) }, + .client = NULL, + }, + { + /* qsfp 19 (0x50) */ + .parent = 68, + .info = { SFF8436_INFO(&sff_8436_port[18]) }, + .client = NULL, + }, + { + /* qsfp 20 (0x50) */ + .parent = 69, + .info = { SFF8436_INFO(&sff_8436_port[19]) }, + .client = NULL, + }, + { + /* qsfp 21 (0x50) */ + .parent = 70, + .info = { SFF8436_INFO(&sff_8436_port[20]) }, + .client = NULL, + }, + { + /* qsfp 22 (0x50) */ + .parent = 71, + .info = { SFF8436_INFO(&sff_8436_port[21]) }, + .client = NULL, + }, + { + /* qsfp 23 (0x50) */ + .parent = 72, + .info = { SFF8436_INFO(&sff_8436_port[22]) }, + .client = NULL, + }, + { + /* qsfp 24 (0x50) */ + .parent = 73, + .info = { SFF8436_INFO(&sff_8436_port[23]) }, + .client = NULL, + }, + { + /* qsfp 25 (0x50) */ + .parent = 74, + .info = { SFF8436_INFO(&sff_8436_port[24]) }, + .client = NULL, + }, + { + /* qsfp 26 (0x50) */ + .parent = 75, + .info = { SFF8436_INFO(&sff_8436_port[25]) }, + .client = NULL, + }, + { + /* qsfp 27 (0x50) */ + .parent = 76, + .info = { SFF8436_INFO(&sff_8436_port[26]) }, + .client = NULL, + }, + { + /* qsfp 28 (0x50) */ + .parent = 77, + .info = { SFF8436_INFO(&sff_8436_port[27]) }, + .client = NULL, + }, + { + /* qsfp 29 (0x50) */ + .parent = 78, + .info = { SFF8436_INFO(&sff_8436_port[28]) }, + .client = NULL, + }, + { + /* qsfp 30 (0x50) */ + .parent = 79, + .info = { SFF8436_INFO(&sff_8436_port[29]) }, + .client = NULL, + }, + { + /* qsfp 31 (0x50) */ + .parent = 80, + .info = { SFF8436_INFO(&sff_8436_port[30]) }, + .client = NULL, + }, + { + /* qsfp 32 (0x50) */ + .parent = 81, + .info = { SFF8436_INFO(&sff_8436_port[31]) }, + .client = NULL, + }, +}; + + +static struct platform_device ag9032v1_i2c_device[] = { + ag9032v1_i2c_device_num(0), + ag9032v1_i2c_device_num(1), + ag9032v1_i2c_device_num(2), + ag9032v1_i2c_device_num(3), + ag9032v1_i2c_device_num(4), + ag9032v1_i2c_device_num(5), + ag9032v1_i2c_device_num(6), + ag9032v1_i2c_device_num(7), + ag9032v1_i2c_device_num(8), + ag9032v1_i2c_device_num(9), + ag9032v1_i2c_device_num(10), + ag9032v1_i2c_device_num(11), + ag9032v1_i2c_device_num(12), + ag9032v1_i2c_device_num(13), + ag9032v1_i2c_device_num(14), + ag9032v1_i2c_device_num(15), + ag9032v1_i2c_device_num(16), + ag9032v1_i2c_device_num(17), + ag9032v1_i2c_device_num(18), + ag9032v1_i2c_device_num(19), + ag9032v1_i2c_device_num(20), + ag9032v1_i2c_device_num(21), + ag9032v1_i2c_device_num(22), + ag9032v1_i2c_device_num(23), + ag9032v1_i2c_device_num(24), + ag9032v1_i2c_device_num(25), + ag9032v1_i2c_device_num(26), + ag9032v1_i2c_device_num(27), + ag9032v1_i2c_device_num(28), + ag9032v1_i2c_device_num(29), + ag9032v1_i2c_device_num(30), + ag9032v1_i2c_device_num(31), + ag9032v1_i2c_device_num(32), + ag9032v1_i2c_device_num(33), + ag9032v1_i2c_device_num(34), + ag9032v1_i2c_device_num(35), + ag9032v1_i2c_device_num(36), + ag9032v1_i2c_device_num(37), + ag9032v1_i2c_device_num(38), + ag9032v1_i2c_device_num(39), + ag9032v1_i2c_device_num(40), + ag9032v1_i2c_device_num(41), + ag9032v1_i2c_device_num(42), + ag9032v1_i2c_device_num(43), +}; + +/*---------------- I2C device - end ------------- */ + +/*---------------- I2C driver - start ------------- */ +static int __init i2c_device_probe(struct platform_device *pdev) +{ + struct i2c_device_platform_data *pdata; + struct i2c_adapter *parent; + + pdata = pdev->dev.platform_data; + if (!pdata) { + dev_err(&pdev->dev, "Missing platform data\n"); + return -ENODEV; + } + + parent = i2c_get_adapter(pdata->parent); + if (!parent) { + dev_err(&pdev->dev, "Parent adapter (%d) not found\n", + pdata->parent); + return -ENODEV; + } + + pdata->client = i2c_new_device(parent, &pdata->info); + if (!pdata->client) { + dev_err(&pdev->dev, "Failed to create i2c client %s at %d\n", + pdata->info.type, pdata->parent); + return -ENODEV; + } + + return 0; +} + +static int __exit i2c_deivce_remove(struct platform_device *pdev) +{ + struct i2c_adapter *parent; + struct i2c_device_platform_data *pdata; + + pdata = pdev->dev.platform_data; + if (!pdata) { + dev_err(&pdev->dev, "Missing platform data\n"); + return -ENODEV; + } + + if (pdata->client) { + parent = i2c_get_adapter(pdata->parent); + i2c_unregister_device(pdata->client); + i2c_put_adapter(parent); + } + + return 0; +} +static struct platform_driver i2c_device_driver = { + .probe = i2c_device_probe, + .remove = __exit_p(i2c_deivce_remove), + .driver = { + .owner = THIS_MODULE, + .name = "delta-ag9032v1-i2c-device", + } +}; + +/*---------------- I2C driver - end ------------- */ + +/*---------------- CPLD - start ------------- */ + +/* CPLD -- device */ + +enum cpld_type { + system_cpld, +}; + +struct cpld_platform_data { + int reg_addr; + struct i2c_client *client; +}; + +static struct cpld_platform_data ag9032v1_cpld_platform_data[] = { + [system_cpld] = { + .reg_addr = SWPLD_REG, + }, +}; + +static struct platform_device ag9032v1_cpld = { + .name = "delta-ag9032v1-cpld", + .id = 0, + .dev = { + .platform_data = ag9032v1_cpld_platform_data, + .release = device_release + }, +}; + +static ssize_t get_present(struct device *dev, struct device_attribute \ + *dev_attr, char *buf) +{ + int ret; + u32 data = 0; + struct cpld_platform_data *pdata = dev->platform_data; + + ret = i2c_smbus_read_byte_data(pdata[system_cpld].client, SFP_PRESENCE_1); + if (ret < 0) + return sprintf(buf, "error number(%ld)",ret); + data = (u32)reverse_8bits(ret) & 0xff; + + ret = i2c_smbus_read_byte_data(pdata[system_cpld].client, SFP_PRESENCE_2); + if (ret < 0) + return sprintf(buf, "error number(%ld)",ret); + data |= (u32)(reverse_8bits(ret) & 0xff) << 8; + + ret = i2c_smbus_read_byte_data(pdata[system_cpld].client, SFP_PRESENCE_3); + if (ret < 0) + return sprintf(buf, "error number(%ld)",ret); + data |= (u32)(reverse_8bits(ret) & 0xff) << 16; + + ret = i2c_smbus_read_byte_data(pdata[system_cpld].client, SFP_PRESENCE_4); + if (ret < 0) + return sprintf(buf, "error number(%ld)",ret); + data |= (u32)(reverse_8bits(ret) & 0xff) << 24; + + return sprintf(buf, "0x%08x\n", data); //return 32bits data +} + +static ssize_t get_lpmode(struct device *dev, struct device_attribute *devattr, char *buf) +{ + int ret; + u32 data = 0; + struct cpld_platform_data *pdata = dev->platform_data; + + ret = i2c_smbus_read_byte_data(pdata[system_cpld].client, SFP_LP_MODE_1); + if (ret < 0) + return sprintf(buf, "error number(%ld)",ret); + data = (u32)(reverse_8bits(ret) & 0xff); + + ret = i2c_smbus_read_byte_data(pdata[system_cpld].client, SFP_LP_MODE_2); + if (ret < 0) + return sprintf(buf, "error number(%ld)",ret); + data |= (u32)(reverse_8bits(ret) & 0xff) << 8; + + ret = i2c_smbus_read_byte_data(pdata[system_cpld].client, SFP_LP_MODE_3); + if (ret < 0) + return sprintf(buf, "error number(%ld)",ret); + data |= (u32)(reverse_8bits(ret) & 0xff) << 16; + + ret = i2c_smbus_read_byte_data(pdata[system_cpld].client, SFP_LP_MODE_4); + if (ret < 0) + return sprintf(buf, "error number(%ld)",ret); + data |= (u32)(reverse_8bits(ret) & 0xff) << 24; + + return sprintf(buf, "0x%08x\n", data); //return 32bits data +} + +static ssize_t set_lpmode(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) +{ + unsigned long data; + int err; + struct cpld_platform_data *pdata = dev->platform_data; + + err = kstrtoul(buf, 16, &data); + if (err) + return err; + + i2c_smbus_write_byte_data(pdata[system_cpld].client, SFP_LP_MODE_1, (u8)reverse_8bits(data & 0xff)); + i2c_smbus_write_byte_data(pdata[system_cpld].client, SFP_LP_MODE_2, (u8)(reverse_8bits(data >> 8) & 0xff)); + i2c_smbus_write_byte_data(pdata[system_cpld].client, SFP_LP_MODE_3, (u8)(reverse_8bits(data >> 16) & 0xff)); + i2c_smbus_write_byte_data(pdata[system_cpld].client, SFP_LP_MODE_4, (u8)(reverse_8bits(data >> 24) & 0xff)); + + return count; +} + +static ssize_t get_reset(struct device *dev, struct device_attribute *devattr, char *buf) +{ + int ret; + u32 data = 0; + struct cpld_platform_data *pdata = dev->platform_data; + + ret = i2c_smbus_read_byte_data(pdata[system_cpld].client, SFP_RESET_1); + if (ret < 0) + return sprintf(buf, "error number(%ld)",ret); + data = (u32)(reverse_8bits(ret) & 0xff); + + ret = i2c_smbus_read_byte_data(pdata[system_cpld].client, SFP_RESET_2); + if (ret < 0) + return sprintf(buf, "error number(%ld)",ret); + data |= (u32)(reverse_8bits(ret) & 0xff) << 8; + + ret = i2c_smbus_read_byte_data(pdata[system_cpld].client, SFP_RESET_3); + if (ret < 0) + return sprintf(buf, "error number(%ld)",ret); + data |= (u32)(reverse_8bits(ret) & 0xff) << 16; + + ret = i2c_smbus_read_byte_data(pdata[system_cpld].client, SFP_RESET_4); + if (ret < 0) + return sprintf(buf, "error number(%ld)",ret); + data |= (u32)(reverse_8bits(ret) & 0xff) << 24; + + return sprintf(buf, "0x%08x\n", data); //return 32bits data +} + +static ssize_t set_reset(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) +{ + unsigned long data; + int err; + struct cpld_platform_data *pdata = dev->platform_data; + + err = kstrtoul(buf, 16, &data); + if (err) + return err; + + i2c_smbus_write_byte_data(pdata[system_cpld].client, SFP_RESET_1, (u8)reverse_8bits(data & 0xff)); + i2c_smbus_write_byte_data(pdata[system_cpld].client, SFP_RESET_2, (u8)reverse_8bits((data >> 8)& 0xff)); + i2c_smbus_write_byte_data(pdata[system_cpld].client, SFP_RESET_3, (u8)reverse_8bits((data >> 16) & 0xff)); + i2c_smbus_write_byte_data(pdata[system_cpld].client, SFP_RESET_4, (u8)reverse_8bits((data >> 24) & 0xff)); + + return count; +} + +static ssize_t get_response(struct device *dev, struct device_attribute *devattr, char *buf) +{ + int ret; + u32 data = 0; + struct cpld_platform_data *pdata = dev->platform_data; + + ret = i2c_smbus_read_byte_data(pdata[system_cpld].client, SFP_RESPONSE_1); + if (ret < 0) + return sprintf(buf, "error number(%ld)",ret); + data = (u32)(reverse_8bits(ret) & 0xff); + + ret = i2c_smbus_read_byte_data(pdata[system_cpld].client, SFP_RESPONSE_2); + if (ret < 0) + return sprintf(buf, "error number(%ld)",ret); + data |= (u32)(reverse_8bits(ret) & 0xff) << 8; + + ret = i2c_smbus_read_byte_data(pdata[system_cpld].client, SFP_RESPONSE_3); + if (ret < 0) + return sprintf(buf, "error number(%ld)",ret); + data |= (u32)(reverse_8bits(ret) & 0xff) << 16; + + ret = i2c_smbus_read_byte_data(pdata[system_cpld].client, SFP_RESPONSE_4); + if (ret < 0) + return sprintf(buf, "error number(%ld)",ret); + data |= (u32)(reverse_8bits(ret) & 0xff) << 24; + + return sprintf(buf, "0x%08x\n", data); //return 32bits data +} + +static ssize_t set_response(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) +{ + unsigned long data; + int err; + struct cpld_platform_data *pdata = dev->platform_data; + + err = kstrtoul(buf, 16, &data); + if (err) + return err; + + i2c_smbus_write_byte_data(pdata[system_cpld].client, SFP_RESPONSE_1, (u8)reverse_8bits(data & 0xff)); + i2c_smbus_write_byte_data(pdata[system_cpld].client, SFP_RESPONSE_2, (u8)reverse_8bits((data >> 8)& 0xff)); + i2c_smbus_write_byte_data(pdata[system_cpld].client, SFP_RESPONSE_3, (u8)reverse_8bits((data >> 16) & 0xff)); + i2c_smbus_write_byte_data(pdata[system_cpld].client, SFP_RESPONSE_4, (u8)reverse_8bits((data >> 24) & 0xff)); + + return count; +} + +struct platform_led_status{ + int reg_data; + char *led_status; + int led_id; +}; + +static struct platform_led_status led_info[] = { + { + .reg_data = 0x40, + .led_status = "pwr1_green", + .led_id = 0, + }, + { + .reg_data = 0x80, + .led_status = "pwr1_amber", + .led_id = 0, + }, + { + .reg_data = 0x00, + .led_status = "pwr1_off", + .led_id = 0, + }, + { + .reg_data = 0xc0, + .led_status = "pwr1_off", + .led_id = 0, + }, + { + .reg_data = 0x10, + .led_status = "pwr2_green", + .led_id = 1, + }, + { + .reg_data = 0x20, + .led_status = "pwr2_amber", + .led_id = 1, + }, + { + .reg_data = 0x00, + .led_status = "pwr2_off", + .led_id = 1, + }, + { + .reg_data = 0x30, + .led_status = "pwr2_off", + .led_id = 1, + }, + { + .reg_data = 0x04, + .led_status = "sys_green", + .led_id = 2, + }, + { + .reg_data = 0x08, + .led_status = "sys_blinking_green", + .led_id = 2, + }, + { + .reg_data = 0x0c, + .led_status = "sys_red", + .led_id = 2, + }, + { + .reg_data = 0x00, + .led_status = "sys_off", + .led_id = 2, + }, + { + .reg_data = 0x01, + .led_status = "fan_green", + .led_id = 3, + }, + { + .reg_data = 0x02, + .led_status = "fan_amber", + .led_id = 3, + }, + { + .reg_data = 0x00, + .led_status = "fan_off", + .led_id = 3, + }, + { + .reg_data = 0x03, + .led_status = "fan_off", + .led_id = 3, + }, + { + .reg_data = 0x40, + .led_status = "fan1_green", + .led_id = 4, + }, + { + .reg_data = 0x80, + .led_status = "fan1_red", + .led_id = 4, + }, + { + .reg_data = 0x00, + .led_status = "fan1_off", + .led_id = 4, + }, + { + .reg_data = 0x10, + .led_status = "fan2_green", + .led_id = 5, + }, + { + .reg_data = 0x20, + .led_status = "fan2_red", + .led_id = 5, + }, + { + .reg_data = 0x00, + .led_status = "fan2_off", + .led_id = 5, + }, + { + .reg_data = 0x04, + .led_status = "fan3_green", + .led_id = 6, + }, + { + .reg_data = 0x08, + .led_status = "fan3_red", + .led_id = 6, + }, + { + .reg_data = 0x00, + .led_status = "fan3_off", + .led_id = 6, + }, + { + .reg_data = 0x01, + .led_status = "fan4_green", + .led_id = 7, + }, + { + .reg_data = 0x02, + .led_status = "fan4_red", + .led_id = 7, + }, + { + .reg_data = 0x00, + .led_status = "fan4_off", + .led_id = 7, + }, + { + .reg_data = 0x40, + .led_status = "fan5_green", + .led_id = 8, + }, + { + .reg_data = 0x80, + .led_status = "fan5_red", + .led_id = 8, + }, + { + .reg_data = 0x00, + .led_status = "fan5_off", + .led_id = 8, + }, +}; + +struct platform_led_data{ + int reg_addr; + int mask; +}; + +static struct platform_led_data led_data[] = { + { + .reg_addr = SYS_LED_REG, + .mask = 0xc0, + }, + { + .reg_addr = SYS_LED_REG, + .mask = 0x30, + }, + { + .reg_addr = SYS_LED_REG, + .mask = 0x0c, + }, + { + .reg_addr = SYS_LED_REG, + .mask = 0x03, + }, + { + .reg_addr = FAN1_LED_REG, + .mask = 0xc0, + }, + { + .reg_addr = FAN1_LED_REG, + .mask = 0x30, + }, + { + .reg_addr = FAN1_LED_REG, + .mask = 0x0c, + }, + { + .reg_addr = FAN1_LED_REG, + .mask = 0x03, + }, + { + .reg_addr = FAN2_LED_REG, + .mask = 0xc0, + }, +}; + + +static ssize_t get_led_color(struct device *dev, struct device_attribute *devattr, char *buf) +{ + char str[9][20] = {0}; + int board_data; + int led_data_number; + int led_info_number; + struct cpld_platform_data *pdata = dev->platform_data; + + for(led_data_number = 0; led_data_number < ARRAY_SIZE(led_data); led_data_number++){ + board_data = i2c_smbus_read_byte_data(pdata[system_cpld].client, led_data[led_data_number].reg_addr); + if(board_data >= 0){ + board_data &= led_data[led_data_number].mask; + for(led_info_number = 0; led_info_number < ARRAY_SIZE(led_info); led_info_number++){ + if (led_data_number == led_info[led_info_number].led_id){ + if(board_data == led_info[led_info_number].reg_data){ + sprintf(str[led_data_number], "%s", led_info[led_info_number].led_status); + } + } + } + } + else + printk( KERN_ERR "Missing LED board data\n"); + } + return sprintf(buf,"%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n",str[0],str[1],str[2],str[3],str[4],str[5],str[6],str[7],str[8]); +} + +static ssize_t set_led_color(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) +{ + int led_info_number; + int led_data_number; + int str_compar; + int led_reg_value; + struct cpld_platform_data *pdata = dev->platform_data; + + for(led_info_number = 0; led_info_number < ARRAY_SIZE(led_info); led_info_number++){ + str_compar = strncmp(buf,led_info[led_info_number].led_status,strlen(led_info[led_info_number].led_status)); + if(str_compar == 0){ + for(led_data_number = 0; led_data_number < ARRAY_SIZE(led_data); led_data_number++){ + if(led_info[led_info_number].led_id == led_data_number){ + led_reg_value = i2c_smbus_read_byte_data(pdata[system_cpld].client, led_data[led_data_number].reg_addr); + if(led_reg_value >= 0){ + led_reg_value &= (~led_data[led_data_number].mask); + led_reg_value |= led_info[led_info_number].reg_data; + i2c_smbus_write_byte_data(pdata[system_cpld].client, (u8)(led_data[led_data_number].reg_addr & 0xff), (u8)(led_reg_value & 0xff)); + } + else + printk( KERN_ERR "Missing LED reg. data\n"); + } + } + } + } + return count; +} + + +static DEVICE_ATTR(sfp_present, S_IRUGO, get_present, NULL ); +static DEVICE_ATTR(sfp_lpmode, S_IWUSR | S_IRUGO, get_lpmode, set_lpmode ); +static DEVICE_ATTR(sfp_reset, S_IWUSR | S_IRUGO, get_reset, set_reset ); +static DEVICE_ATTR(sfp_response, S_IWUSR | S_IRUGO, get_response, set_response ); +static DEVICE_ATTR(led_control, S_IRUGO | S_IWUSR, get_led_color, set_led_color); + +static struct attribute *ag9032v1_cpld_attrs[] = { + &dev_attr_sfp_response.attr, + &dev_attr_sfp_present.attr, + &dev_attr_sfp_lpmode.attr, + &dev_attr_sfp_reset.attr, + &dev_attr_led_control.attr, + NULL, +}; + +static struct attribute_group ag9032v1_cpld_attr_grp = { + .attrs = ag9032v1_cpld_attrs, +}; + +/* CPLD -- driver */ +static int __init cpld_probe(struct platform_device *pdev) +{ + struct cpld_platform_data *pdata; + struct i2c_adapter *parent; + int ret; + pdata = pdev->dev.platform_data; + if (!pdata) { + dev_err(&pdev->dev, "CPLD platform data not found\n"); + return -ENODEV; + } + + parent = i2c_get_adapter(BUS6); + if (!parent) { + printk(KERN_WARNING "Parent adapter (%d) not found\n",BUS6); + return -ENODEV; + } + + pdata[system_cpld].client = i2c_new_dummy(parent, pdata[system_cpld].reg_addr); + if (!pdata[system_cpld].client) { + printk(KERN_WARNING "Fail to create dummy i2c client for addr %d\n", pdata[system_cpld].reg_addr); + goto error; + } + + ret = sysfs_create_group(&pdev->dev.kobj, &ag9032v1_cpld_attr_grp); + if (ret) { + printk(KERN_WARNING "Fail to create cpld attribute group"); + goto error; + } + + return 0; + +error: + i2c_unregister_device(pdata[system_cpld].client); + i2c_put_adapter(parent); + + return -ENODEV; +} + +static int __exit cpld_remove(struct platform_device *pdev) +{ + struct i2c_adapter *parent = NULL; + struct cpld_platform_data *pdata = pdev->dev.platform_data; + sysfs_remove_group(&pdev->dev.kobj, &ag9032v1_cpld_attr_grp); + + if (!pdata) { + dev_err(&pdev->dev, "Missing platform data\n"); + } + else { + if (pdata[system_cpld].client) { + if (!parent) { + parent = (pdata[system_cpld].client)->adapter; + } + i2c_unregister_device(pdata[system_cpld].client); + } + } + i2c_put_adapter(parent); + + return 0; +} + +static struct platform_driver cpld_driver = { + .probe = cpld_probe, + .remove = __exit_p(cpld_remove), + .driver = { + .owner = THIS_MODULE, + .name = "delta-ag9032v1-cpld", + }, +}; + +/*---------------- CPLD - end ------------- */ + +/*---------------- MUX - start ------------- */ + +struct swpld_mux_platform_data { + int parent; + int base_nr; + int reg_addr; + struct i2c_client *cpld; +}; + +struct swpld_mux { + struct i2c_adapter *parent; + struct i2c_adapter **child; + struct swpld_mux_platform_data data; +}; +static struct swpld_mux_platform_data ag9032v1_swpld_mux_platform_data[] = { + { + .parent = BUS3, + .base_nr = BUS3_BASE_NUM, + .cpld = NULL, + .reg_addr = BUS3_MUX_REG ,// the i2c register address which for select mux TEMP(FAN) + }, + { + .parent = BUS4, + .base_nr = BUS4_BASE_NUM , + .cpld = NULL, + .reg_addr = BUS4_MUX_REG , + }, + { + .parent = BUS5, + .base_nr = BUS5_BASE_NUM , + .cpld = NULL, + .reg_addr = BUS5_MUX_REG , + }, +}; + +static struct platform_device ag9032v1_swpld_mux[] = { + { + .name = "delta-ag9032v1-swpld-mux", + .id = 0, + .dev = { + .platform_data = &ag9032v1_swpld_mux_platform_data[0], + .release = device_release, + }, + }, + { + .name = "delta-ag9032v1-swpld-mux", + .id = 1, + .dev = { + .platform_data = &ag9032v1_swpld_mux_platform_data[1], + .release = device_release, + }, + }, + { + .name = "delta-ag9032v1-swpld-mux", + .id = 2, + .dev = { + .platform_data = &ag9032v1_swpld_mux_platform_data[2], + .release = device_release, + }, + }, +}; + +static int cpld_reg_write_byte(struct i2c_client *client, u8 regaddr, u8 val) +{ + union i2c_smbus_data data; + + data.byte = val; + return client->adapter->algo->smbus_xfer(client->adapter, client->addr, + client->flags, + I2C_SMBUS_WRITE, + regaddr, I2C_SMBUS_BYTE_DATA, &data); +} + +static int swpld_mux_select(struct i2c_adapter *adap, void *data, u8 chan) +{ + struct swpld_mux *mux = data; + u8 swpld_mux_val=0; + + if ( mux->data.base_nr == BUS3_BASE_NUM ) + { + switch (chan) { + case 0: + swpld_mux_val = TEMP_FAN_VAL; + break; + case 1: + swpld_mux_val = FAN_EEPROM1_VAL; + break; + case 2: + swpld_mux_val = FAN_EEPROM2_VAL; + break; + case 3: + swpld_mux_val = FAN_EEPROM3_VAL; + break; + case 4: + swpld_mux_val = FAN_EEPROM4_VAL; + break; + case 5: + swpld_mux_val = FAN_EEPROM5_VAL; + break; + case 6: + swpld_mux_val = FANIO_CTL_VAL; + break; + case 7: + case 8: + swpld_mux_val = FAN_CTRL_VAL; + break; + } + } + else if ( mux->data.base_nr == BUS4_BASE_NUM ) + { + switch (chan) { + case 0: + swpld_mux_val = PSU1_VAL; + break; + case 1: + swpld_mux_val = PSU2_VAL; + break; + case 2: + swpld_mux_val = HOT_SWAP1_VAL; + break; + case 3: + swpld_mux_val = HOT_SWAP2_VAL; + break; + } + } + else if ( mux->data.base_nr == BUS5_BASE_NUM ){ + if (chan < 9){ + swpld_mux_val = (u8)(chan) + 0x01; + } + else if (8 < chan && chan < 19){ + swpld_mux_val = (u8)(chan - 9) + 0x10; + } + else if (18 < chan && chan < 29){ + swpld_mux_val = (u8)(chan - 19) + 0x20; + } + else if (28 < chan && chan < 39){ + swpld_mux_val = (u8)(chan - 29) + 0x30; + } + else{ + swpld_mux_val = 0x00; + } + } + else + { + swpld_mux_val = 0x00; + } + return cpld_reg_write_byte(mux->data.cpld, mux->data.reg_addr, (u8)(swpld_mux_val & 0xff)); +} + +static int __init swpld_mux_probe(struct platform_device *pdev) +{ + struct swpld_mux *mux; + struct swpld_mux_platform_data *pdata; + struct i2c_adapter *parent; + int i, ret, dev_num; + + pdata = pdev->dev.platform_data; + if (!pdata) { + dev_err(&pdev->dev, "SWPLD platform data not found\n"); + return -ENODEV; + } + + parent = i2c_get_adapter(pdata->parent); + if (!parent) { + dev_err(&pdev->dev, "Parent adapter (%d) not found\n", pdata->parent); + return -ENODEV; + } + /* Judge bus number to decide how many devices*/ + switch (pdata->parent) { + case BUS3: + dev_num = BUS3_DEV_NUM; + break; + case BUS4: + dev_num = BUS4_DEV_NUM; + break; + case BUS5: + dev_num = BUS5_DEV_NUM; + break; + default : + dev_num = DEFAULT_NUM; + break; + } + + mux = kzalloc(sizeof(*mux), GFP_KERNEL); + if (!mux) { + ret = -ENOMEM; + printk(KERN_ERR "Failed to allocate memory for mux\n"); + goto alloc_failed; + } + + mux->parent = parent; + mux->data = *pdata; + mux->child = kzalloc(sizeof(struct i2c_adapter *) * dev_num, GFP_KERNEL); + if (!mux->child) { + ret = -ENOMEM; + printk(KERN_ERR "Failed to allocate memory for device on mux\n"); + goto alloc_failed2; + } + + for (i = 0; i < dev_num; i++) { + int nr = pdata->base_nr + i; + unsigned int class = 0; + + mux->child[i] = i2c_add_mux_adapter(parent, &pdev->dev, mux, + nr, i, class, + swpld_mux_select, NULL); + if (!mux->child[i]) { + ret = -ENODEV; + dev_err(&pdev->dev, "Failed to add adapter %d\n", i); + goto add_adapter_failed; + } + } + + platform_set_drvdata(pdev, mux); + return 0; + +add_adapter_failed: + for (; i > 0; i--) + i2c_del_mux_adapter(mux->child[i - 1]); + kfree(mux->child); +alloc_failed2: + kfree(mux); +alloc_failed: + i2c_put_adapter(parent); + + return ret; +} + + +static int __exit swpld_mux_remove(struct platform_device *pdev) +{ + int i; + struct swpld_mux *mux = platform_get_drvdata(pdev); + struct swpld_mux_platform_data *pdata; + struct i2c_adapter *parent; + int dev_num; + + pdata = pdev->dev.platform_data; + if (!pdata) { + dev_err(&pdev->dev, "SWPLD platform data not found\n"); + return -ENODEV; + } + + parent = i2c_get_adapter(pdata->parent); + if (!parent) { + dev_err(&pdev->dev, "Parent adapter (%d) not found\n", + pdata->parent); + return -ENODEV; + } + switch (pdata->parent) { + case BUS3: + dev_num = BUS3_DEV_NUM; + break; + case BUS4: + dev_num = BUS4_DEV_NUM; + break; + case BUS5: + dev_num = BUS5_DEV_NUM; + break; + default : + dev_num = DEFAULT_NUM; + break; + } + + for (i = 0; i < dev_num; i++) + i2c_del_mux_adapter(mux->child[i]); + + platform_set_drvdata(pdev, NULL); + i2c_put_adapter(mux->parent); + kfree(mux->child); + kfree(mux); + + return 0; +} + +static struct platform_driver swpld_mux_driver = { + .probe = swpld_mux_probe, + .remove = __exit_p(swpld_mux_remove), /* TODO */ + .driver = { + .owner = THIS_MODULE, + .name = "delta-ag9032v1-swpld-mux", + }, +}; +/*---------------- MUX - end ------------- */ + +/*---------------- module initialization ------------- */ +static void __init delta_ag9032v1_platform_init(void) +{ + struct i2c_client *client; + struct i2c_adapter *adapter; + struct cpld_platform_data *cpld_pdata; + struct swpld_mux_platform_data *swpld_pdata; + int ret,i = 0; + printk("ag9032v1_platform module initialization\n"); + + //Use pca9547 in i2c_mux_pca954x.c + adapter = i2c_get_adapter(BUS1); + //client = i2c_new_device(adapter, &i2c_info_pca9547[0]); + i2c_client_9547 = i2c_new_device(adapter, &i2c_info_pca9547[0]); + + i2c_put_adapter(adapter); + + // set the CPLD prob and remove + ret = platform_driver_register(&cpld_driver); + if (ret) { + printk(KERN_WARNING "Fail to register cpld driver\n"); + goto error_cpld_driver; + } + // register the mux prob which call the CPLD + ret = platform_driver_register(&swpld_mux_driver); + if (ret) { + printk(KERN_WARNING "Fail to register swpld mux driver\n"); + goto error_swpld_mux_driver; + } + + // register the i2c devices + ret = platform_driver_register(&i2c_device_driver); + if (ret) { + printk(KERN_WARNING "Fail to register i2c device driver\n"); + goto error_i2c_device_driver; + } + + // register the CPLD + ret = platform_device_register(&ag9032v1_cpld); + if (ret) { + printk(KERN_WARNING "Fail to create cpld device\n"); + goto error_ag9032v1_cpld; + } + // link the CPLD and the Mux + cpld_pdata = ag9032v1_cpld.dev.platform_data; + + for (i = 0; i < ARRAY_SIZE(ag9032v1_swpld_mux); i++) + { + swpld_pdata = ag9032v1_swpld_mux[i].dev.platform_data; + swpld_pdata->cpld = cpld_pdata[system_cpld].client; + ret = platform_device_register(&ag9032v1_swpld_mux[i]); + if (ret) { + printk(KERN_WARNING "Fail to create swpld mux %d\n", i); + goto error_ag9032v1_swpld_mux; + } + } + + for (i = 0; i < ARRAY_SIZE(ag9032v1_i2c_device); i++) + { + ret = platform_device_register(&ag9032v1_i2c_device[i]); + if (ret) { + printk(KERN_WARNING "Fail to create i2c device %d\n", i); + goto error_ag9032v1_i2c_device; + } + } + + if (ret) + goto error_ag9032v1_swpld_mux; + + return 0; + +error_ag9032v1_i2c_device: + i--; + for (; i >= 0; i--) { + platform_device_unregister(&ag9032v1_i2c_device[i]); + } + i = ARRAY_SIZE(ag9032v1_swpld_mux); +error_ag9032v1_swpld_mux: + i--; + for (; i >= 0; i--) { + platform_device_unregister(&ag9032v1_swpld_mux[i]); + } + platform_driver_unregister(&ag9032v1_cpld); +error_ag9032v1_cpld: + platform_driver_unregister(&i2c_device_driver); +error_i2c_device_driver: + platform_driver_unregister(&swpld_mux_driver); +error_swpld_mux_driver: + platform_driver_unregister(&cpld_driver); +error_cpld_driver: + return ret; +} + +static void __exit delta_ag9032v1_platform_exit(void) +{ + int i = 0; + + for ( i = 0; i < ARRAY_SIZE(ag9032v1_i2c_device); i++ ) { + platform_device_unregister(&ag9032v1_i2c_device[i]); + } + + for (i = 0; i < ARRAY_SIZE(ag9032v1_swpld_mux); i++) { + platform_device_unregister(&ag9032v1_swpld_mux[i]); + } + + platform_device_unregister(&ag9032v1_cpld); + platform_driver_unregister(&i2c_device_driver); + platform_driver_unregister(&cpld_driver); + platform_driver_unregister(&swpld_mux_driver); + + i2c_unregister_device(i2c_client_9547); +} + +module_init(delta_ag9032v1_platform_init); +module_exit(delta_ag9032v1_platform_exit); + +MODULE_DESCRIPTION("DNI ag9032v1 Platform Support"); +MODULE_AUTHOR("Neal Tai "); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-delta/ag9032v1/modules/dni_ag9032v1_psu.c b/platform/broadcom/sonic-platform-modules-delta/ag9032v1/modules/dni_ag9032v1_psu.c new file mode 100644 index 000000000000..b9ddb979a29b --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-delta/ag9032v1/modules/dni_ag9032v1_psu.c @@ -0,0 +1,545 @@ +/* + * An hwmon driver for delta AG9032v1 PSU + * dps_800ab_16_d.c - Support for DPS-800AB-16 D Power Supply Module + * + * Copyright (C) 2017 Delta Networks, Inc. + * + * Aries Lin + * + * Based on ym2651y.c + * Based on ad7414.c + * + * 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 MAX_FAN_DUTY_CYCLE 100 +#define SWPLD_REG 0x31 +#define SWPLD_PSU_MUX_REG 0x21 +#define SELECT_PSU1_EEPROM 0x00 +#define SELECT_PSU2_EEPROM 0x20 + +u8 psu_member_data = 0x00; + +/* Address scanned */ +static const unsigned short normal_i2c[] = { 0x58, I2C_CLIENT_END }; + +/* This is additional data */ +struct dps_800ab_16_d_data { + struct device *hwmon_dev; + struct mutex update_lock; + char valid; + unsigned long last_updated; /* In jiffies */ + + /* Registers value */ + u8 vout_mode; + u16 in1_input; + u16 in2_input; + u16 curr1_input; + u16 curr2_input; + u16 power1_input; + u16 power2_input; + u16 temp_input[2]; + u8 fan_target; + u16 fan_duty_cycle_input[2]; + u16 fan_speed_input[2]; + u8 mfr_model[16]; + u8 mfr_serial[16]; +}; + +static int two_complement_to_int(u16 data, u8 valid_bit, int mask); +static ssize_t set_fan_duty_cycle_input(struct device *dev, struct device_attribute \ + *dev_attr, const char *buf, size_t count); +static ssize_t for_linear_data(struct device *dev, struct device_attribute \ + *dev_attr, char *buf); +static ssize_t for_fan_target(struct device *dev, struct device_attribute \ + *dev_attr, char *buf); +static ssize_t for_vout_data(struct device *dev, struct device_attribute \ + *dev_attr, char *buf); +static int dps_800ab_16_d_read_byte(struct i2c_client *client, u8 reg); +static int dps_800ab_16_d_read_word(struct i2c_client *client, u8 reg); +static int dps_800ab_16_d_write_word(struct i2c_client *client, u8 reg, \ + u16 value); +static int dps_800ab_16_d_read_block(struct i2c_client *client, u8 command, \ + u8 *data, int data_len); +static struct dps_800ab_16_d_data *dps_800ab_16_d_update_device( \ + struct device *dev); +static ssize_t for_ascii(struct device *dev, struct device_attribute \ + *dev_attr, char *buf); +static ssize_t set_w_member_data(struct device *dev, struct device_attribute \ + *dev_att, const char *buf, size_t count); +static ssize_t for_r_member_data(struct device *dev, struct device_attribute \ + *dev_attr, char *buf); + +enum dps_800ab_16_d_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, + PSU_MFR_MODEL, + PSU_MFR_SERIAL, + PSU_SELECT_MEMBER, +}; + +static ssize_t set_w_member_data(struct device *dev, struct device_attribute \ + *dev_attr, const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + long data; + int error; + if (attr->index == PSU_SELECT_MEMBER) { + error = kstrtol(buf, 16, &data); + if (error) + return error; + if (SELECT_PSU1_EEPROM == data) { + psu_member_data = SELECT_PSU1_EEPROM; + } else if (SELECT_PSU2_EEPROM == data) { + psu_member_data = SELECT_PSU2_EEPROM; + } else { + return -EINVAL; + } + } + return count; +} + +static ssize_t for_r_member_data(struct device *dev, struct device_attribute \ + *dev_attr, char *buf) +{ + return sprintf(buf, "0x%02X\n", psu_member_data); +} + +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_input(struct device *dev, struct device_attribute \ + *dev_attr, const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct i2c_client *client = to_i2c_client(dev); + struct dps_800ab_16_d_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; + + /* Select SWPLD PSU offset */ + + mutex_lock(&data->update_lock); + data->fan_duty_cycle_input[nr] = speed; + dps_800ab_16_d_write_word(client, 0x3B + nr, data->fan_duty_cycle_input[nr]); + mutex_unlock(&data->update_lock); + + return count; +} + +static ssize_t for_linear_data(struct device *dev, struct device_attribute \ + *dev_attr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct dps_800ab_16_d_data *data = dps_800ab_16_d_update_device(dev); + + u16 value = 0; + int exponent, mantissa; + int multiplier = 1000; + + switch (attr->index) { + case PSU_V_IN: + value = data->in1_input; + break; + case PSU_I_IN: + value = data->curr1_input; + break; + case PSU_I_OUT: + value = data->curr2_input; + break; + case PSU_P_IN: + value = data->power1_input; + multiplier = 1000*1000; + break; + case PSU_P_OUT: + value = data->power2_input; + multiplier = 1000*1000; + break; + case PSU_TEMP1_INPUT: + value = data->temp_input[0]; + break; + case PSU_FAN1_DUTY_CYCLE: + multiplier = 1; + value = data->fan_duty_cycle_input[0]; + break; + case PSU_FAN1_SPEED: + multiplier = 1; + value = data->fan_speed_input[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 for_fan_target(struct device *dev, struct device_attribute \ + *dev_attr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct dps_800ab_16_d_data *data = dps_800ab_16_d_update_device(dev); + + u8 shift = (attr->index == PSU_FAN1_FAULT) ? 7 : 6; + + return sprintf(buf, "%d\n", data->fan_target >> shift); +} + +static ssize_t for_vout_data(struct device *dev, struct device_attribute \ + *dev_attr, char *buf) +{ + struct dps_800ab_16_d_data *data = dps_800ab_16_d_update_device(dev); + int exponent, mantissa; + int multiplier = 1000; + + exponent = two_complement_to_int(data->vout_mode, 5, 0x1f); + mantissa = data->in2_input; + + return (exponent > 0) ? sprintf(buf, "%d\n", \ + (mantissa * multiplier) / (1 << exponent)): \ + sprintf(buf, "%d\n", (mantissa * multiplier) / (1 << -exponent)); +} + +static ssize_t for_ascii(struct device *dev, struct device_attribute \ + *dev_attr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct dps_800ab_16_d_data *data = dps_800ab_16_d_update_device(dev); + u8 *ptr = NULL; + + if (!data->valid) + return 0; + + switch (attr->index) { + case PSU_MFR_MODEL: + ptr = data->mfr_model + 1; + break; + case PSU_MFR_SERIAL: + ptr = data->mfr_serial + 1; + break; + default: + return 0; + } + return sprintf(buf, "%s\n", ptr); +} +static int dps_800ab_16_d_read_byte(struct i2c_client *client, u8 reg) +{ + return i2c_smbus_read_byte_data(client, reg); +} + +static int dps_800ab_16_d_read_word(struct i2c_client *client, u8 reg) +{ + return i2c_smbus_read_word_data(client, reg); +} + +static int dps_800ab_16_d_write_word(struct i2c_client *client, u8 reg, \ + u16 value) +{ + union i2c_smbus_data data; + data.word = value; + return i2c_smbus_xfer(client->adapter, client->addr, + client->flags |= I2C_CLIENT_PEC, + I2C_SMBUS_WRITE, reg, + I2C_SMBUS_WORD_DATA, &data); + +} + +static int dps_800ab_16_d_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 dps_800ab_16_d_data *dps_800ab_16_d_update_device( \ + struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct dps_800ab_16_d_data *data = i2c_get_clientdata(client); + + mutex_lock(&data->update_lock); + + /* Select SWPLD PSU offset */ + + if (time_after(jiffies, data->last_updated)) { + int i, status; + u8 command; + struct reg_data_byte regs_byte[] = { + {0x20, &data->vout_mode}, + {0x81, &data->fan_target} + }; + struct reg_data_word regs_word[] = { + {0x88, &data->in1_input}, + {0x8b, &data->in2_input}, + {0x89, &data->curr1_input}, + {0x8c, &data->curr2_input}, + {0x96, &data->power2_input}, + {0x97, &data->power1_input}, + {0x8d, &(data->temp_input[0])}, + {0x8e, &(data->temp_input[1])}, + {0x3b, &(data->fan_duty_cycle_input[0])}, + {0x90, &(data->fan_speed_input[0])}, + }; + + dev_dbg(&client->dev, "start data update\n"); + + /* one milliseconds from now */ + data->last_updated = jiffies + HZ / 1000; + + for (i = 0; i < ARRAY_SIZE(regs_byte); i++) { + status = dps_800ab_16_d_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; + } + } + + for (i = 0; i < ARRAY_SIZE(regs_word); i++) { + status = dps_800ab_16_d_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; + } + } + + command = 0x9a; /* PSU mfr_model */ + status = dps_800ab_16_d_read_block(client, command, + data->mfr_model, ARRAY_SIZE(data->mfr_model) - 1); + data->mfr_model[ARRAY_SIZE(data->mfr_model) - 1] = '\0'; + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", command, + status); + } + + command = 0x9e; /* PSU mfr_serial */ + status = dps_800ab_16_d_read_block(client, command, + data->mfr_serial, ARRAY_SIZE(data->mfr_serial) - 1); + data->mfr_serial[ARRAY_SIZE(data->mfr_serial) - 1] = '\0'; + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", command, + status); + } + + data->valid = 1; + } + + mutex_unlock(&data->update_lock); + + return data; + +} + +/* sysfs attributes for hwmon */ +static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, for_linear_data, NULL, PSU_V_IN); +static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, for_vout_data, NULL, PSU_V_OUT); +static SENSOR_DEVICE_ATTR(curr1_input, S_IRUGO, for_linear_data, NULL, PSU_I_IN); +static SENSOR_DEVICE_ATTR(curr2_input, S_IRUGO, for_linear_data, NULL, PSU_I_OUT); +static SENSOR_DEVICE_ATTR(power1_input, S_IRUGO, for_linear_data, NULL, PSU_P_IN); +static SENSOR_DEVICE_ATTR(power2_input, S_IRUGO, for_linear_data, NULL, PSU_P_OUT); +static SENSOR_DEVICE_ATTR(temp1_input, \ + S_IRUGO, for_linear_data, NULL, PSU_TEMP1_INPUT); +static SENSOR_DEVICE_ATTR(fan1_target, \ + S_IRUGO, for_fan_target, NULL, PSU_FAN1_FAULT); +static SENSOR_DEVICE_ATTR(fan1_set_percentage, S_IWUGO | S_IRUGO, \ + for_linear_data, set_fan_duty_cycle_input, PSU_FAN1_DUTY_CYCLE); +static SENSOR_DEVICE_ATTR(fan1_input, \ + S_IRUGO, for_linear_data, NULL, PSU_FAN1_SPEED); +static SENSOR_DEVICE_ATTR(psu_mfr_model, \ + S_IRUGO, for_ascii, NULL, PSU_MFR_MODEL); +static SENSOR_DEVICE_ATTR(psu_mfr_serial, \ + S_IRUGO, for_ascii, NULL, PSU_MFR_SERIAL); +static SENSOR_DEVICE_ATTR(psu_select_member, S_IWUGO | S_IRUGO, \ + for_r_member_data, set_w_member_data, PSU_SELECT_MEMBER); + +static struct attribute *dps_800ab_16_d_attributes[] = { + &sensor_dev_attr_in1_input.dev_attr.attr, + &sensor_dev_attr_in2_input.dev_attr.attr, + &sensor_dev_attr_curr1_input.dev_attr.attr, + &sensor_dev_attr_curr2_input.dev_attr.attr, + &sensor_dev_attr_power1_input.dev_attr.attr, + &sensor_dev_attr_power2_input.dev_attr.attr, + &sensor_dev_attr_temp1_input.dev_attr.attr, + &sensor_dev_attr_fan1_target.dev_attr.attr, + &sensor_dev_attr_fan1_set_percentage.dev_attr.attr, + &sensor_dev_attr_fan1_input.dev_attr.attr, + &sensor_dev_attr_psu_mfr_model.dev_attr.attr, + &sensor_dev_attr_psu_mfr_serial.dev_attr.attr, + &sensor_dev_attr_psu_select_member.dev_attr.attr, + NULL +}; + +static const struct attribute_group dps_800ab_16_d_group = { + .attrs = dps_800ab_16_d_attributes, +}; + +static int dps_800ab_16_d_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct dps_800ab_16_d_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(*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, "new chip found\n"); + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &dps_800ab_16_d_group); + if (status) + goto exit_sysfs_create_group; + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + status = PTR_ERR(data->hwmon_dev); + goto exit_hwmon_device_register; + } + + return 0; + +exit_hwmon_device_register: + sysfs_remove_group(&client->dev.kobj, &dps_800ab_16_d_group); +exit_sysfs_create_group: + kfree(data); +exit: + return status; +} + +static int dps_800ab_16_d_remove(struct i2c_client *client) +{ + struct dps_800ab_16_d_data *data = i2c_get_clientdata(client); + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &dps_800ab_16_d_group); + kfree(data); + + return 0; +} + +enum id_name { + dni_ag9032v1_psu, + dps_800ab_16_d +}; + +static const struct i2c_device_id dps_800ab_16_d_id[] = { + { "dni_ag9032v1_psu", dni_ag9032v1_psu }, + { "dps_800ab_16_d", dps_800ab_16_d }, + {} +}; +MODULE_DEVICE_TABLE(i2c, dps_800ab_16_d_id); + +/* This is the driver that will be inserted */ +static struct i2c_driver dps_800ab_16_d_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "dps_800ab_16_d", + }, + .probe = dps_800ab_16_d_probe, + .remove = dps_800ab_16_d_remove, + .id_table = dps_800ab_16_d_id, + .address_list = normal_i2c, +}; + +static int __init dps_800ab_16_d_init(void) +{ + return i2c_add_driver(&dps_800ab_16_d_driver); +} + +static void __exit dps_800ab_16_d_exit(void) +{ + i2c_del_driver(&dps_800ab_16_d_driver); +} + + +MODULE_AUTHOR("Aries Lin "); +MODULE_DESCRIPTION("DPS_800AB_16_D Driver"); +MODULE_LICENSE("GPL"); + +module_init(dps_800ab_16_d_init); +module_exit(dps_800ab_16_d_exit); diff --git a/platform/broadcom/sonic-platform-modules-delta/ag9032v1/modules/dni_emc2305.c b/platform/broadcom/sonic-platform-modules-delta/ag9032v1/modules/dni_emc2305.c new file mode 100644 index 000000000000..73d9900af5b4 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-delta/ag9032v1/modules/dni_emc2305.c @@ -0,0 +1,381 @@ +/* + * + * + * Copyright (C) 2017 Delta Networks, Inc. + * + * This program is free software; you can redistribute it + * and/or modify it under the terms ofthe GNU General Public License as + * published by the Free Software Foundation; either version 2 of the License, + * or (at your option) any later version. + * + * + * + * + * + * A hwmon driver for the SMSC EMC2305 fan controller + * Complete datasheet is available (6/2013) at: + * http://www.smsc.com/media/Downloads_Public/Data_Sheets/2305.pdf + */ + +#include +#include +#include +#include +#include + + +static ssize_t set_pwm(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count); +static ssize_t show_pwm(struct device *dev, struct device_attribute *devattr, + char *buf); +static ssize_t set_fan(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count); +static ssize_t show_fan(struct device *dev, struct device_attribute *devattr, + char *buf); +static ssize_t set_fan_percentage(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count); +static ssize_t show_fan_percentage(struct device *dev, struct device_attribute * devattr, + char *buf); +static const unsigned short normal_i2c[] = { 0x2C, 0x2D, 0x2E, 0x2F, 0x4C, + 0x4D, I2C_CLIENT_END + }; + + +#define EMC2305_REG_DEVICE 0xFD +#define EMC2305_REG_VENDOR 0xFE + +//#define FAN_MINIMUN 0x33 /*20%*/ +#define FAN_MINIMUN 0x0 /*0%*/ +#define FAN_RPM_BASED 0xAB + +#define EMC2305_REG_FAN_DRIVE(n) (0x30 + 0x10 * n) +#define EMC2305_REG_FAN_MIN_DRIVE(n) (0x38 + 0x10 * n) +#define EMC2305_REG_FAN_TACH(n) (0x3E + 0x10 * n) +#define EMC2305_REG_FAN_CONF(n) (0x32 + 0x10 * n) +#define EMC2305_REG_FAN_REAR_H_RPM(n) (0x3D + 0x10 * n) +#define EMC2305_REG_FAN_REAR_L_RPM(n) (0x3C + 0x10 * n) + +#define EMC2305_DEVICE 0x34 +#define EMC2305_VENDOR 0x5D +#define MAX_FAN_SPEED 23000 + +struct emc2305_data +{ + struct device *hwmon_dev; + struct attribute_group attrs; + struct mutex lock; +}; + +static int emc2305_probe(struct i2c_client *client, + const struct i2c_device_id *id); +static int emc2305_detect(struct i2c_client *client, + struct i2c_board_info *info); +static int emc2305_remove(struct i2c_client *client); + +static const struct i2c_device_id emc2305_id[] = +{ + { "emc2305", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, emc2305_id); + +static struct i2c_driver emc2305_driver = +{ + .class = I2C_CLASS_HWMON, + .driver = { + .name = "emc2305", + }, + .probe = emc2305_probe, + .remove = emc2305_remove, + .id_table = emc2305_id, + .detect = emc2305_detect, + .address_list = normal_i2c, +}; + +static SENSOR_DEVICE_ATTR(fan1_input, S_IWUSR | S_IRUGO, show_fan, set_fan, 0); +static SENSOR_DEVICE_ATTR(fan2_input, S_IWUSR | S_IRUGO, show_fan, set_fan, 1); +static SENSOR_DEVICE_ATTR(fan3_input, S_IWUSR | S_IRUGO, show_fan, set_fan, 2); +static SENSOR_DEVICE_ATTR(fan4_input, S_IWUSR | S_IRUGO, show_fan, set_fan, 3); +static SENSOR_DEVICE_ATTR(fan5_input, S_IWUSR | S_IRUGO, show_fan, set_fan, 4); +static SENSOR_DEVICE_ATTR(fan1_input_percentage, S_IWUSR | S_IRUGO, show_fan_percentage, set_fan_percentage, 0); +static SENSOR_DEVICE_ATTR(fan2_input_percentage, S_IWUSR | S_IRUGO, show_fan_percentage, set_fan_percentage, 1); +static SENSOR_DEVICE_ATTR(fan3_input_percentage, S_IWUSR | S_IRUGO, show_fan_percentage, set_fan_percentage, 2); +static SENSOR_DEVICE_ATTR(fan4_input_percentage, S_IWUSR | S_IRUGO, show_fan_percentage, set_fan_percentage, 3); +static SENSOR_DEVICE_ATTR(fan5_input_percentage, S_IWUSR | S_IRUGO, show_fan_percentage, set_fan_percentage, 4); +static SENSOR_DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 0); +static SENSOR_DEVICE_ATTR(pwm2, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 1); +static SENSOR_DEVICE_ATTR(pwm3, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 2); +static SENSOR_DEVICE_ATTR(pwm4, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 3); +static SENSOR_DEVICE_ATTR(pwm5, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 4); + +static struct attribute *emc2305_attr[] = +{ + &sensor_dev_attr_fan1_input.dev_attr.attr, + &sensor_dev_attr_fan2_input.dev_attr.attr, + &sensor_dev_attr_fan3_input.dev_attr.attr, + &sensor_dev_attr_fan4_input.dev_attr.attr, + &sensor_dev_attr_fan5_input.dev_attr.attr, + &sensor_dev_attr_fan1_input_percentage.dev_attr.attr, + &sensor_dev_attr_fan2_input_percentage.dev_attr.attr, + &sensor_dev_attr_fan3_input_percentage.dev_attr.attr, + &sensor_dev_attr_fan4_input_percentage.dev_attr.attr, + &sensor_dev_attr_fan5_input_percentage.dev_attr.attr, + &sensor_dev_attr_pwm1.dev_attr.attr, + &sensor_dev_attr_pwm2.dev_attr.attr, + &sensor_dev_attr_pwm3.dev_attr.attr, + &sensor_dev_attr_pwm4.dev_attr.attr, + &sensor_dev_attr_pwm5.dev_attr.attr, + NULL +}; + +static ssize_t show_fan_percentage(struct device *dev, struct device_attribute * devattr, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct i2c_client *client = to_i2c_client(dev); + struct emc2305_data *data = i2c_get_clientdata(client); + int val; + + mutex_lock(&data->lock); + val = i2c_smbus_read_word_swapped(client, + EMC2305_REG_FAN_TACH(attr->index)); + mutex_unlock(&data->lock); + /* Left shift 3 bits for showing correct RPM */ + val = val >> 3; + if ((int)(3932160 * 2 / (val > 0 ? val : 1) == 960))return sprintf(buf, "%d\n", 0); + return sprintf(buf, "%d\n", (int)(3932160 * 2 / (val > 0 ? val : 1) * 100 / MAX_FAN_SPEED)); +} + + +static ssize_t set_fan_percentage(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct i2c_client *client = to_i2c_client(dev); + struct emc2305_data *data = i2c_get_clientdata(client); + unsigned long hsb, lsb; + unsigned long tech; + unsigned long val; + int ret; + + ret = kstrtoul(buf, 10, &val); + if (ret) + { + return ret; + } + if (val > 100) + { + return -EINVAL; + } + + if (val <= 5) + { + hsb = 0xff; /*high bit*/ + lsb = 0xe0; /*low bit*/ + } + else + { + val = val * 230; + tech = (3932160 * 2) / (val > 0 ? val : 1); + hsb = (uint8_t)(((tech << 3) >> 8) & 0x0ff); + lsb = (uint8_t)((tech << 3) & 0x0f8); + } + + mutex_lock(&data->lock); + i2c_smbus_write_byte_data(client, EMC2305_REG_FAN_REAR_H_RPM(attr->index), hsb); + i2c_smbus_write_byte_data(client, EMC2305_REG_FAN_REAR_L_RPM(attr->index), lsb); + mutex_unlock(&data->lock); + return count; +} + + +static ssize_t show_fan(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct i2c_client *client = to_i2c_client(dev); + struct emc2305_data *data = i2c_get_clientdata(client); + int val; + + + mutex_lock(&data->lock); + val = i2c_smbus_read_word_swapped(client, + EMC2305_REG_FAN_TACH(attr->index)); + mutex_unlock(&data->lock); + /* Left shift 3 bits for showing correct RPM */ + val = val >> 3; + return sprintf(buf, "%d\n", 3932160 * 2 / (val > 0 ? val : 1)); +} + +static ssize_t set_fan(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct i2c_client *client = to_i2c_client(dev); + struct emc2305_data *data = i2c_get_clientdata(client); + unsigned long hsb, lsb; + unsigned long tech; + unsigned long val; + int ret; + + ret = kstrtoul(buf, 10, &val); + if (ret) + { + return ret; + } + if (val > 23000) + { + return -EINVAL; + } + + if (val <= 960) + { + hsb = 0xff; /*high bit*/ + lsb = 0xe0; /*low bit*/ + } + else + { + tech = (3932160 * 2) / (val > 0 ? val : 1); + hsb = (uint8_t)(((tech << 3) >> 8) & 0x0ff); + lsb = (uint8_t)((tech << 3) & 0x0f8); + } + + mutex_lock(&data->lock); + i2c_smbus_write_byte_data(client, EMC2305_REG_FAN_REAR_H_RPM(attr->index), hsb); + i2c_smbus_write_byte_data(client, EMC2305_REG_FAN_REAR_L_RPM(attr->index), lsb); + mutex_unlock(&data->lock); + return count; +} + +static ssize_t show_pwm(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct i2c_client *client = to_i2c_client(dev); + struct emc2305_data *data = i2c_get_clientdata(client); + int val; + + mutex_lock(&data->lock); + val = i2c_smbus_read_byte_data(client, + EMC2305_REG_FAN_DRIVE(attr->index)); + mutex_unlock(&data->lock); + return sprintf(buf, "%d\n", val); +} + +static ssize_t set_pwm(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct i2c_client *client = to_i2c_client(dev); + struct emc2305_data *data = i2c_get_clientdata(client); + unsigned long val; + int ret; + + ret = kstrtoul(buf, 10, &val); + if (ret) + { + return ret; + } + if (val > 255) + { + return -EINVAL; + } + + mutex_lock(&data->lock); + i2c_smbus_write_byte_data(client, + EMC2305_REG_FAN_DRIVE(attr->index), + val); + mutex_unlock(&data->lock); + return count; +} + +static int emc2305_detect(struct i2c_client *client, + struct i2c_board_info *info) +{ + struct i2c_adapter *adapter = client->adapter; + int vendor, device; + + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA | + I2C_FUNC_SMBUS_WORD_DATA)) + { + return -ENODEV; + } + + vendor = i2c_smbus_read_byte_data(client, EMC2305_REG_VENDOR); + if (vendor != EMC2305_VENDOR) + { + return -ENODEV; + } + + device = i2c_smbus_read_byte_data(client, EMC2305_REG_DEVICE); + if (device != EMC2305_DEVICE) + { + return -ENODEV; + } + + strlcpy(info->type, "emc2305", I2C_NAME_SIZE); + + return 0; +} + +static int emc2305_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct emc2305_data *data; + int err; + int i; + + data = devm_kzalloc(&client->dev, sizeof(struct emc2305_data), + GFP_KERNEL); + if (!data) + { + return -ENOMEM; + } + + i2c_set_clientdata(client, data); + mutex_init(&data->lock); + + dev_info(&client->dev, "%s chip found\n", client->name); + + data->attrs.attrs = emc2305_attr; + err = sysfs_create_group(&client->dev.kobj, &data->attrs); + if (err) + { + return err; + } + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) + { + err = PTR_ERR(data->hwmon_dev); + goto exit_remove; + } + + for (i = 0; i < 5; i++) + { + /* set minimum drive to 0% */ + i2c_smbus_write_byte_data(client, EMC2305_REG_FAN_MIN_DRIVE(i), FAN_MINIMUN); + i2c_smbus_write_byte_data(client, EMC2305_REG_FAN_CONF(i), FAN_RPM_BASED); + } + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &data->attrs); + return err; +} + +static int emc2305_remove(struct i2c_client *client) +{ + struct emc2305_data *data = i2c_get_clientdata(client); + + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &data->attrs); + return 0; +} + +module_i2c_driver(emc2305_driver); + +MODULE_AUTHOR("Neal Tai"); +MODULE_DESCRIPTION("SMSC EMC2305 fan controller driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-delta/ag9032v1/scripts/ag9032v1_platform_init.sh b/platform/broadcom/sonic-platform-modules-delta/ag9032v1/scripts/ag9032v1_platform_init.sh new file mode 100755 index 000000000000..c5f897ff007f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-delta/ag9032v1/scripts/ag9032v1_platform_init.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +#platform init script for Delta ag9032v1 + +#fan speed monitol start +/usr/share/sonic/device/x86_64-delta_ag9032v1-r0/fancontrol.service /usr/share/sonic/device/x86_64-delta_ag9032v1-r0/fancontrol & + +exit 0 + diff --git a/platform/broadcom/sonic-platform-modules-delta/ag9032v1/scripts/led_status.sh b/platform/broadcom/sonic-platform-modules-delta/ag9032v1/scripts/led_status.sh new file mode 100755 index 000000000000..5685bd71f58c --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-delta/ag9032v1/scripts/led_status.sh @@ -0,0 +1,225 @@ +#!/bin/bash + +FAN1_EEPROM="-y 31 0x51 0x0a" +FAN2_EEPROM="-y 32 0x52 0x0a" +FAN3_EEPROM="-y 33 0x53 0x0a" +FAN4_EEPROM="-y 34 0x54 0x0a" +FAN5_EEPROM="-y 35 0x55 0x0a" +LED_CONTROL="/sys/devices/platform/delta-ag9032v1-cpld.0/led_control" +FAN1_FRONT_RPM="/sys/devices/pci0000:00/0000:00:13.0/i2c-1/i2c-3/i2c-37/37-002c/fan5_input" +FAN1_REAR_RPM="/sys/devices/pci0000:00/0000:00:13.0/i2c-1/i2c-3/i2c-38/38-002d/fan5_input" +FAN2_FRONT_RPM="/sys/devices/pci0000:00/0000:00:13.0/i2c-1/i2c-3/i2c-37/37-002c/fan4_input" +FAN2_REAR_RPM="/sys/devices/pci0000:00/0000:00:13.0/i2c-1/i2c-3/i2c-38/38-002d/fan4_input" +FAN3_FRONT_RPM="/sys/devices/pci0000:00/0000:00:13.0/i2c-1/i2c-3/i2c-37/37-002c/fan3_input" +FAN3_REAR_RPM="/sys/devices/pci0000:00/0000:00:13.0/i2c-1/i2c-3/i2c-38/38-002d/fan3_input" +FAN4_FRONT_RPM="/sys/devices/pci0000:00/0000:00:13.0/i2c-1/i2c-3/i2c-37/37-002c/fan2_input" +FAN4_REAR_RPM="/sys/devices/pci0000:00/0000:00:13.0/i2c-1/i2c-3/i2c-38/38-002d/fan2_input" +FAN5_FRONT_RPM="/sys/devices/pci0000:00/0000:00:13.0/i2c-1/i2c-3/i2c-37/37-002c/fan1_input" +FAN5_REAR_RPM="/sys/devices/pci0000:00/0000:00:13.0/i2c-1/i2c-3/i2c-38/38-002d/fan1_input" + +PSU1_EEPROM="-y 40 0x50 0x00" +PSU2_EEPROM="-y 41 0x50 0x00" +PSU1_FAN_RPM="/sys/devices/pci0000:00/0000:00:13.0/i2c-1/i2c-4/i2c-40/40-0058/fan1_input" +PSU2_FAN_RPM="/sys/devices/pci0000:00/0000:00:13.0/i2c-1/i2c-4/i2c-41/41-0058/fan1_input" + +catfaneeprom(){ + fan_eeprom_num=0 + i2cget $FAN1_EEPROM > /dev/null 2>&1 + if [ "`echo $?`" -eq "0" ]; then + fan_eeprom_num=$((fan_eeprom_num+1)) + elif [ "`echo $?`" -eq "2" ]; then + fan_eeprom_num=$((fan_eeprom_num)) + fi + i2cget $FAN2_EEPROM > /dev/null 2>&1 + if [ "`echo $?`" -eq "0" ]; then + fan_eeprom_num=$((fan_eeprom_num+1)) + elif [ "`echo $?`" -eq "2" ]; then + fan_eeprom_num=$((fan_eeprom_num_num)) + fi + + i2cget $FAN3_EEPROM > /dev/null 2>&1 + if [ "`echo $?`" -eq "0" ]; then + fan_eeprom_num=$((fan_eeprom_num+1)) + elif [ "`echo $?`" -eq "2" ]; then + fan_eeprom_num=$((fan_eeprom_num)) + fi + + i2cget $FAN4_EEPROM > /dev/null 2>&1 + if [ "`echo $?`" -eq "0" ]; then + fan_eeprom_num=$((fan_eeprom_num+1)) + elif [ "`echo $?`" -eq "2" ]; then + fan_eeprom_num=$((fan_eeprom_num)) + fi + + i2cget $FAN5_EEPROM > /dev/null 2>&1 + if [ "`echo $?`" -eq "0" ]; then + fan_eeprom_num=$((fan_eeprom_num+1)) + elif [ "`echo $?`" -eq "2" ]; then + fan_eeprom_num=$((fan_eeprom_num)) + fi +} + +catfanspeed(){ + fan_rpm_normal_num=0 + fan1_rpm_normal_num=0 + fan1_front_rpm=`cat $FAN1_FRONT_RPM` + fan1_rear_rpm=`cat $FAN1_REAR_RPM` + if [ "${fan1_front_rpm}" -ne "960" ] && [ "${fan1_rear_rpm}" -ne "960" ] && [ "${fan1_front_rpm}" -ne "0" ] && [ "${fan1_rear_rpm}" -ne "0" ]; then + fan1_rpm_normal_num=$((fan1_rpm_normal_num+1)) + elif [ "${fan1_front_rpm}" -eq "960" ] || [ "${fan1_rear_rpm}" -eq "960" ] || [ "${fan1_front_rpm}" -eq "0" ] || [ "${fan1_rear_rpm}" -eq "0" ]; then + fan1_rpm_normal_num=$((fan1_rpm_normal_num)) + fi + + fan2_rpm_normal_num=0 + fan2_front_rpm=`cat $FAN2_FRONT_RPM` + fan2_rear_rpm=`cat $FAN2_REAR_RPM` + if [ "${fan2_front_rpm}" -ne "960" ] && [ "${fan2_rear_rpm}" -ne "960" ] && [ "${fan2_front_rpm}" -ne "0" ] && [ "${fan2_rear_rpm}" -ne "0" ]; then + fan2_rpm_normal_num=$((fan2_rpm_normal_num+1)) + elif [ "${fan2_front_rpm}" -eq "960" ] || [ "${fan2_rear_rpm}" -eq "960" ] || [ "${fan2_front_rpm}" -eq "0" ] || [ "${fan2_rear_rpm}" -eq "0" ]; then + fan2_rpm_normal_num=$((fan2_rpm_normal_num)) + fi + + fan3_rpm_normal_num=0 + fan3_front_rpm=`cat $FAN3_FRONT_RPM` + fan3_rear_rpm=`cat $FAN3_REAR_RPM` + if [ "${fan3_front_rpm}" -ne "960" ] && [ "${fan3_rear_rpm}" -ne "960" ] && [ "${fan3_front_rpm}" -ne "0" ] && [ "${fan3_rear_rpm}" -ne "0" ]; then + fan3_rpm_normal_num=$((fan3_rpm_normal_num+1)) + elif [ "${fan3_front_rpm}" -eq "960" ] || [ "${fan3_rear_rpm}" -eq "960" ] || [ "${fan3_front_rpm}" -eq "0" ] || [ "${fan3_rear_rpm}" -eq "0" ]; then + fan3_rpm_normal_num=$((fan3_rpm_normal_num)) + fi + + fan4_rpm_normal_num=0 + fan4_front_rpm=`cat $FAN4_FRONT_RPM` + fan4_rear_rpm=`cat $FAN4_REAR_RPM` + if [ "${fan4_front_rpm}" -ne "960" ] && [ "${fan4_rear_rpm}" -ne "960" ] && [ "${fan4_front_rpm}" -ne "0" ] && [ "${fan4_rear_rpm}" -ne "0" ]; then + fan4_rpm_normal_num=$((fan4_rpm_normal_num+1)) + elif [ "${fan4_front_rpm}" -eq "960" ] || [ "${fan4_rear_rpm}" -eq "960" ] || [ "${fan4_front_rpm}" -eq "0" ] || [ "${fan4_rear_rpm}" -eq "0" ]; then + fan4_rpm_normal_num=$((fan4_rpm_normal_num)) + fi + + fan5_rpm_normal_num=0 + fan5_front_rpm=`cat $FAN5_FRONT_RPM` + fan5_rear_rpm=`cat $FAN5_REAR_RPM` + if [ "${fan5_front_rpm}" -ne "960" ] && [ "${fan5_rear_rpm}" -ne "960" ] && [ "${fan5_front_rpm}" -ne "0" ] && [ "${fan5_rear_rpm}" -ne "0" ]; then + fan5_rpm_normal_num=$((fan5_rpm_normal_num+1)) + elif [ "${fan5_front_rpm}" -eq "960" ] || [ "${fan5_rear_rpm}" -eq "960" ] || [ "${fan5_front_rpm}" -eq "0" ] || [ "${fan5_rear_rpm}" -eq "0" ]; then + fan5_rpm_normal_num=$((fan5_rpm_normal_num)) + fi + + fan_rpm_normal_num=$((fan1_rpm_normal_num+fan2_rpm_normal_num+fan3_rpm_normal_num+fan4_rpm_normal_num+fan5_rpm_normal_num)) + +} + +catpsueeprom(){ + psu1_eeprom_num=0 + i2cget $PSU1_EEPROM > /dev/null 2>&1 + if [ "`echo $?`" -eq "0" ]; then + psu1_eeprom_num=$((psu1_eeprom_num+1)) + elif [ "`echo $?`" -eq "2" ]; then + psu1_eeprom_num=$((psu1_eeprom_num)) + fi + + psu2_eeprom_num=0 + i2cget $PSU2_EEPROM > /dev/null 2>&1 + if [ "`echo $?`" -eq "0" ]; then + psu2_eeprom_num=$((psu2_eeprom_num+1)) + elif [ "`echo $?`" -eq "2" ]; then + psu2_eeprom_num=$((psu2_eeprom_num)) + fi +} + +catpsufanspeed(){ + + psu1_rpm_normal_num=0 + psu1_rpm=`cat $PSU1_FAN_RPM` + + if [ "${psu1_rpm}" -ne "960" ] && [ "${psu1_rpm}" -ne "0" ]; then + psu1_rpm_normal_num=$((psu1_rpm_normal_num+1)) + elif [ "${psu1_rpm}" -eq "960" ] || [ "${psu1_rpm}" -eq "0" ]; then + psu1_rpm_normal_num=$((psu1_rpm_normal_num)) + fi + + psu2_rpm_normal_num=0 + psu2_rpm=`cat $PSU2_FAN_RPM` + + if [ "${psu2_rpm}" -ne "960" ] && [ "${psu2_rpm}" -ne "0" ]; then + psu2_rpm_normal_num=$((psu2_rpm_normal_num+1)) + elif [ "${psu2_rpm}" -eq "960" ] || [ "${psu2_rpm}" -eq "0" ]; then + psu2_rpm_normal_num=$((psu2_rpm_normal_num)) + fi + +} + +setfanled(){ + if [ "${fan_eeprom_num}" -eq "5" ] && [ "${fan_rpm_normal_num}" -eq "5" ]; then + echo "fan_green" > $LED_CONTROL + elif [ "${fan_eeprom_num}" -lt "5" ] || [ "${fan_rpm_normal_num}" -lt "5" ]; then + echo "fan_amber" > $LED_CONTROL + fi +} + +setpsuled(){ + if [ "${psu1_eeprom_num}" -eq "1" ] && [ "${psu1_rpm_normal_num}" -eq "1" ]; then + echo "pwr1_green" > $LED_CONTROL + elif [ "${psu1_eeprom_num}" -eq "0" ] || [ "${psu1_rpm_normal_num}" -eq "0" ]; then + echo "pwr1_amber" > $LED_CONTROL + fi + + if [ "${psu2_eeprom_num}" -eq "1" ] && [ "${psu2_rpm_normal_num}" -eq "1" ]; then + echo "pwr2_green" > $LED_CONTROL + elif [ "${psu2_eeprom_num}" -eq "0" ] || [ "${psu2_rpm_normal_num}" -eq "0" ]; then + echo "pwr2_amber" > $LED_CONTROL + fi +} + +setfantrayled(){ + if [ "${fan1_rpm_normal_num}" -eq "1" ]; then + echo "fan1_green" > $LED_CONTROL + else + echo "fan1_red" > $LED_CONTROL + fi + + if [ "${fan2_rpm_normal_num}" -eq "1" ]; then + echo "fan2_green" > $LED_CONTROL + else + echo "fan2_red" > $LED_CONTROL + fi + + if [ "${fan3_rpm_normal_num}" -eq "1" ]; then + echo "fan3_green" > $LED_CONTROL + else + echo "fan3_red" > $LED_CONTROL + fi + + if [ "${fan4_rpm_normal_num}" -eq "1" ]; then + echo "fan4_green" > $LED_CONTROL + else + echo "fan4_red" > $LED_CONTROL + fi + + if [ "${fan5_rpm_normal_num}" -eq "1" ]; then + echo "fan5_green" > $LED_CONTROL + else + echo "fan5_red" > $LED_CONTROL + fi +} + +platformstatus(){ + + echo "sys_green" > $LED_CONTROL + catfaneeprom + catfanspeed + setfanled + setfantrayled + + catpsueeprom + catpsufanspeed + setpsuled +} + +while true +do + platformstatus + sleep 1 +done + diff --git a/platform/broadcom/sonic-platform-modules-delta/debian/changelog b/platform/broadcom/sonic-platform-modules-delta/debian/changelog new file mode 100644 index 000000000000..ec8327e8ae7a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-delta/debian/changelog @@ -0,0 +1,5 @@ +sonic-delta-platform-modules (1.1) unstable; urgency=low + + * Initial release + + -- Neal Tai Fri, 21 APR 2017 11:11:11 -0800 diff --git a/platform/broadcom/sonic-platform-modules-delta/debian/compat b/platform/broadcom/sonic-platform-modules-delta/debian/compat new file mode 100644 index 000000000000..ec635144f600 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-delta/debian/compat @@ -0,0 +1 @@ +9 diff --git a/platform/broadcom/sonic-platform-modules-delta/debian/control b/platform/broadcom/sonic-platform-modules-delta/debian/control new file mode 100644 index 000000000000..7ad1550415be --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-delta/debian/control @@ -0,0 +1,11 @@ +Source: sonic-delta-platform-modules +Section: main +Priority: extra +Maintainer: Neal Tai +Build-Depends: debhelper (>= 8.0.0), bzip2 +Standards-Version: 3.9.3 + +Package: platform-modules-ag9032v1 +Architecture: amd64 +Depends: linux-image-3.16.0-4-amd64 +Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/broadcom/sonic-platform-modules-delta/debian/files b/platform/broadcom/sonic-platform-modules-delta/debian/files new file mode 100644 index 000000000000..ece02f8e80e2 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-delta/debian/files @@ -0,0 +1 @@ +platform-modules-ag9032v1_1.1_amd64.deb main extra diff --git a/platform/broadcom/sonic-platform-modules-delta/debian/platform-modules-ag9032v1.init b/platform/broadcom/sonic-platform-modules-delta/debian/platform-modules-ag9032v1.init new file mode 100755 index 000000000000..9b829652fd57 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-delta/debian/platform-modules-ag9032v1.init @@ -0,0 +1,49 @@ +#!/bin/bash + +### BEGIN INIT INFO +# Provides: setup-board +# Required-Start: +# Required-Stop: +# Should-Start: +# Should-Stop: +# Default-Start: S +# Default-Stop: 0 6 +# Short-Description: Setup ag9032v1 board. +### END INIT INFO + +case "$1" in +start) + echo -n "Setting up board... " + depmod -a + rmmod i2c-i801 + rmmod i2c-ismt + modprobe i2c-dev + modprobe i2c-i801 + modprobe i2c-ismt + modprobe i2c-mux-pca954x + modprobe dni_ag9032v1_psu + modprobe dni_emc2305 + modprobe at24 + modprobe delta_ag9032v1_platform + + /usr/local/bin/ag9032v1_platform_init.sh + + echo "done." + ;; + +stop) + echo "done." + + ;; + +force-reload|restart) + echo "Not supported" + ;; + +*) + echo "Usage: /etc/init.d/platform-modules-ag9032v1.init {start|stop}" + exit 1 + ;; +esac + +exit 0 diff --git a/platform/broadcom/sonic-platform-modules-delta/debian/platform-modules-ag9032v1.install b/platform/broadcom/sonic-platform-modules-delta/debian/platform-modules-ag9032v1.install new file mode 100644 index 000000000000..40f7e56d832d --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-delta/debian/platform-modules-ag9032v1.install @@ -0,0 +1,3 @@ +ag9032v1/scripts/ag9032v1_platform_init.sh usr/local/bin +ag9032v1/scripts/led_status.sh usr/local/bin +ag9032v1/cfg/ag9032v1-modules.conf etc/modules-load.d diff --git a/platform/broadcom/sonic-platform-modules-delta/debian/rules b/platform/broadcom/sonic-platform-modules-delta/debian/rules new file mode 100644 index 000000000000..ae590626c817 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-delta/debian/rules @@ -0,0 +1,33 @@ +#!/usr/bin/make -f + +export INSTALL_MOD_DIR:=extra + +KVERSION ?= $(shell uname -r) +KERNEL_SRC := /lib/modules/$(KVERSION) +MOD_SRC_DIR:= $(shell pwd) +MODULE_DIRS:= ag9032v1 + +%: + dh $@ + +override_dh_auto_build: + (for mod in $(MODULE_DIRS); do \ + make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules; \ + done) + +override_dh_auto_install: + (for mod in $(MODULE_DIRS); do \ + dh_installdirs -pplatform-modules-$${mod} \ + $(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ + cp $(MOD_SRC_DIR)/$${mod}/modules/*.ko \ + debian/platform-modules-$${mod}/$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ + done) + +override_dh_usrlocal: + +override_dh_clean: + dh_clean + (for mod in $(MODULE_DIRS); do \ + make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules clean; \ + done) + diff --git a/platform/broadcom/sonic-platform-modules-ingrasys b/platform/broadcom/sonic-platform-modules-ingrasys index e66b8839da21..1d9ccb21aaf8 160000 --- a/platform/broadcom/sonic-platform-modules-ingrasys +++ b/platform/broadcom/sonic-platform-modules-ingrasys @@ -1 +1 @@ -Subproject commit e66b8839da2180fd586aae040701faf180d59477 +Subproject commit 1d9ccb21aaf868a788fd593ff1c03fdaf150eaf0 diff --git a/platform/cavium/docker-orchagent-cavm.mk b/platform/cavium/docker-orchagent-cavm.mk index 57ebb2fd1534..a171a6c801d7 100644 --- a/platform/cavium/docker-orchagent-cavm.mk +++ b/platform/cavium/docker-orchagent-cavm.mk @@ -16,3 +16,4 @@ $(DOCKER_ORCHAGENT_CAVM)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro $(DOCKER_ORCHAGENT_CAVM)_RUN_OPT += -v /var/log/swss:/var/log/swss:rw $(DOCKER_ORCHAGENT_CAVM)_BASE_IMAGE_FILES += swssloglevel:/usr/bin/swssloglevel +$(DOCKER_ORCHAGENT_CAVM)_FILES += $(ARP_UPDATE_SCRIPT) diff --git a/platform/centec/docker-orchagent-centec.mk b/platform/centec/docker-orchagent-centec.mk index 695e481546b1..e1d7fd6cf0d6 100644 --- a/platform/centec/docker-orchagent-centec.mk +++ b/platform/centec/docker-orchagent-centec.mk @@ -16,3 +16,4 @@ $(DOCKER_ORCHAGENT_CENTEC)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro $(DOCKER_ORCHAGENT_CENTEC)_RUN_OPT += -v /var/log/swss:/var/log/swss:rw $(DOCKER_ORCHAGENT_CENTEC)_BASE_IMAGE_FILES += swssloglevel:/usr/bin/swssloglevel +$(DOCKER_ORCHAGENT_CENTEC)_FILES += $(ARP_UPDATE_SCRIPT) diff --git a/platform/marvell/docker-orchagent-mrvl.mk b/platform/marvell/docker-orchagent-mrvl.mk index 9461cafe2e89..f2cb0c997d75 100644 --- a/platform/marvell/docker-orchagent-mrvl.mk +++ b/platform/marvell/docker-orchagent-mrvl.mk @@ -15,3 +15,4 @@ $(DOCKER_ORCHAGENT_MRVL)_RUN_OPT += -v /host/machine.conf:/host/machine.conf $(DOCKER_ORCHAGENT_MRVL)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro $(DOCKER_ORCHAGENT_MRVL)_BASE_IMAGE_FILES += swssloglevel:/usr/bin/swssloglevel +$(DOCKER_ORCHAGENT_MRVL)_FILES += $(ARP_UPDATE_SCRIPT) diff --git a/platform/mellanox/docker-orchagent-mlnx.mk b/platform/mellanox/docker-orchagent-mlnx.mk index 20aa38335361..6dda3c446b06 100644 --- a/platform/mellanox/docker-orchagent-mlnx.mk +++ b/platform/mellanox/docker-orchagent-mlnx.mk @@ -16,3 +16,4 @@ $(DOCKER_ORCHAGENT_MLNX)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro $(DOCKER_ORCHAGENT_MLNX)_RUN_OPT += -v /var/log/swss:/var/log/swss:rw $(DOCKER_ORCHAGENT_MLNX)_BASE_IMAGE_FILES += swssloglevel:/usr/bin/swssloglevel +$(DOCKER_ORCHAGENT_MLNX)_FILES += $(ARP_UPDATE_SCRIPT) diff --git a/platform/mellanox/fw.mk b/platform/mellanox/fw.mk index 201e5205daf7..3eef7ca37b5f 100644 --- a/platform/mellanox/fw.mk +++ b/platform/mellanox/fw.mk @@ -1,6 +1,6 @@ # mellanox firmware -MLNX_FW_VERSION = 13.1530.0152 +MLNX_FW_VERSION = 13.1534.0164 MLNX_FW_FILE = fw-SPC-rel-$(subst .,_,$(MLNX_FW_VERSION))-EVB.mfa $(MLNX_FW_FILE)_URL = $(MLNX_SDK_BASE_URL)/$(MLNX_FW_FILE) SONIC_ONLINE_FILES += $(MLNX_FW_FILE) diff --git a/platform/mellanox/mlnx-sai.mk b/platform/mellanox/mlnx-sai.mk index 80b6d893da38..1a73cb80a660 100644 --- a/platform/mellanox/mlnx-sai.mk +++ b/platform/mellanox/mlnx-sai.mk @@ -1,7 +1,7 @@ # Mellanox SAI MLNX_SAI_VERSION = SAIRel1.9.2-master -MLNX_SAI_REVISION = 16900748ee3c97bc5836ab3684ee05b8db6ec31b +MLNX_SAI_REVISION = d098a2c89cd700d9c1278e448fd6bb047cbd59e2 export MLNX_SAI_VERSION MLNX_SAI_REVISION diff --git a/platform/mellanox/sdk.mk b/platform/mellanox/sdk.mk index ad34ba84e277..5aaee09fdb1d 100644 --- a/platform/mellanox/sdk.mk +++ b/platform/mellanox/sdk.mk @@ -1,10 +1,10 @@ -MLNX_SDK_BASE_URL = https://github.com/Mellanox/SAI-Implementation/raw/16900748ee3c97bc5836ab3684ee05b8db6ec31b/sdk +MLNX_SDK_BASE_URL = https://github.com/Mellanox/SAI-Implementation/raw/564703412781016766b248b98266bd6f2c161431/sdk MLNX_SDK_VERSION = 4.2.6011 -MLNX_SDK_RDEBS += $(APPLIBS) $(IPROUTE2) $(SX_ACL_RM) $(SX_COMPLIB) \ +MLNX_SDK_RDEBS += $(APPLIBS) $(IPROUTE2_MLNX) $(SX_ACL_RM) $(SX_COMPLIB) \ $(SX_EXAMPLES) $(SX_GEN_UTILS) $(SX_SCEW) $(SX_SDN_HAL) \ $(SXD_LIBS) $(TESTX) -MLNX_SDK_DEBS += $(APPLIBS_DEV) $(IPROUTE2_DEV) $(SX_ACL_RM_DEV) \ +MLNX_SDK_DEBS += $(APPLIBS_DEV) $(IPROUTE2_MLNX_DEV) $(SX_ACL_RM_DEV) \ $(SX_COMPLIB_DEV) $(SX_COMPLIB_DEV_STATIC) $(SX_EXAMPLES_DEV) \ $(SX_GEN_UTILS_DEV) $(SX_SCEW_DEV) $(SX_SCEW_DEV_STATIC) \ $(SX_SDN_HAL_DEV) $(SX_SDN_HAL_DEV_STATIC) $(SXD_LIBS_DEV) \ @@ -14,9 +14,9 @@ APPLIBS = applibs_1.mlnx.$(MLNX_SDK_VERSION)_amd64.deb $(APPLIBS)_DEPENDS += $(SX_COMPLIB) $(SX_GEN_UTILS) $(SXD_LIBS) $(LIBNL3) $(LIBNL_GENL3) APPLIBS_DEV = applibs-dev_1.mlnx.$(MLNX_SDK_VERSION)_amd64.deb $(eval $(call add_derived_package,$(APPLIBS),$(APPLIBS_DEV))) -IPROUTE2 = iproute2_1.mlnx.$(MLNX_SDK_VERSION)_amd64.deb -IPROUTE2_DEV = iproute2-dev_1.mlnx.$(MLNX_SDK_VERSION)_amd64.deb -$(eval $(call add_derived_package,$(IPROUTE2),$(IPROUTE2_DEV))) +IPROUTE2_MLNX = iproute2_1.mlnx.$(MLNX_SDK_VERSION)_amd64.deb +IPROUTE2_MLNX_DEV = iproute2-dev_1.mlnx.$(MLNX_SDK_VERSION)_amd64.deb +$(eval $(call add_derived_package,$(IPROUTE2_MLNX),$(IPROUTE2_MLNX_DEV))) SX_COMPLIB = sx-complib_1.mlnx.$(MLNX_SDK_VERSION)_amd64.deb SX_COMPLIB_DEV = sx-complib-dev_1.mlnx.$(MLNX_SDK_VERSION)_amd64.deb $(eval $(call add_derived_package,$(SX_COMPLIB),$(SX_COMPLIB_DEV))) diff --git a/platform/vs/docker-sonic-vs.mk b/platform/vs/docker-sonic-vs.mk index e9d23db493db..656c53644637 100644 --- a/platform/vs/docker-sonic-vs.mk +++ b/platform/vs/docker-sonic-vs.mk @@ -2,7 +2,16 @@ DOCKER_SONIC_VS = docker-sonic-vs.gz $(DOCKER_SONIC_VS)_PATH = $(PLATFORM_PATH)/docker-sonic-vs -$(DOCKER_SONIC_VS)_DEPENDS += $(SWSS) $(SYNCD_VS) $(REDIS_SERVER) $(REDIS_TOOLS) $(PYTHON_SWSSCOMMON) $(LIBTEAMDCT) $(LIBTEAM_UTILS) $(SONIC_DEVICE_DATA) +$(DOCKER_SONIC_VS)_DEPENDS += $(SWSS) \ + $(SYNCD_VS) \ + $(REDIS_SERVER) \ + $(REDIS_TOOLS) \ + $(PYTHON_SWSSCOMMON) \ + $(LIBTEAMDCT) \ + $(LIBTEAM_UTILS) \ + $(SONIC_DEVICE_DATA) \ + $(SONIC_UTILS) \ + $(IPROUTE2) ifeq ($(SONIC_ROUTING_STACK), quagga) $(DOCKER_SONIC_VS)_DEPENDS += $(QUAGGA) @@ -12,5 +21,8 @@ else $(DOCKER_SONIC_VS)_DEPENDS += $(GOBGP) endif +$(DOCKER_SONIC_VS)_FILES += $(CONFIGDB_LOAD_SCRIPT) \ + $(ARP_UPDATE_SCRIPT) + $(DOCKER_SONIC_VS)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE) SONIC_DOCKER_IMAGES += $(DOCKER_SONIC_VS) diff --git a/platform/vs/docker-sonic-vs/Dockerfile.j2 b/platform/vs/docker-sonic-vs/Dockerfile.j2 index 43f7f678e71e..a26c3f475fa6 100644 --- a/platform/vs/docker-sonic-vs/Dockerfile.j2 +++ b/platform/vs/docker-sonic-vs/Dockerfile.j2 @@ -3,9 +3,13 @@ FROM docker-config-engine ## Make apt-get non-interactive ENV DEBIAN_FRONTEND=noninteractive +COPY ["sonic-dev.gpg.key", "/etc/apt/"] +RUN apt-key add /etc/apt/sonic-dev.gpg.key +RUN echo "deb http://packages.microsoft.com/repos/sonic-dev/ jessie main" >> /etc/apt/sources.list RUN apt-get update RUN apt-get install -y net-tools \ + arping \ ethtool \ tcpdump \ ifupdown \ @@ -26,7 +30,15 @@ RUN apt-get install -y net-tools \ openssh-server \ libc-ares2 \ iproute \ - libpython2.7 + libpython2.7 \ + grub2-common \ + python-click-default-group \ + python-click \ + python-natsort \ + python-tabulate \ + bash-completion \ + libelf1 \ + libmnl0 RUN pip install setuptools RUN pip install py2_ipaddress @@ -51,6 +63,7 @@ RUN sed -ri 's/^(save .*$)/# \1/g; s/^logfile .*$/logfile ""/; \ s/^# syslog-enabled no$/syslog-enabled no/; \ s/^# unixsocket/unixsocket/; \ + s/notify-keyspace-events ""/notify-keyspace-events AKE/; \ s/^client-output-buffer-limit pubsub [0-9]+mb [0-9]+mb [0-9]+/client-output-buffer-limit pubsub 0 0 0/ \ ' /etc/redis/redis.conf @@ -58,7 +71,10 @@ COPY ["50-default.conf", "/etc/rsyslog.d/"] COPY ["start.sh", "orchagent.sh", "/usr/bin/"] COPY ["brcm.profile.ini", "/usr/share/sonic/device/vswitch/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] +COPY ["files/configdb-load.sh", "/usr/bin/"] +COPY ["files/arp_update", "/usr/bin"] RUN echo "docker-sonic-vs" > /etc/hostname +RUN touch /etc/quagga/zebra.conf ENTRYPOINT ["/usr/bin/supervisord"] diff --git a/platform/vs/docker-sonic-vs/sonic-dev.gpg.key b/platform/vs/docker-sonic-vs/sonic-dev.gpg.key new file mode 100644 index 000000000000..fb9a37901bc7 --- /dev/null +++ b/platform/vs/docker-sonic-vs/sonic-dev.gpg.key @@ -0,0 +1,30 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG v1 + +mQENBFQ1bTIBCAC7oGfkv/ck0XsLuG8cdcSB2ISqxFAcBvH9BitEtxmpW2uhykKk +xY4rVD/4Uys1s3PF1/64QfPR+hYcewueOwz0ZAcLyFXXk4McICXaPq3NrLiWYKKX +UZLnrPzcrGZoW/kHDDp4OmBiDmT1PGvZlpuimwkMCusUzIr7Cbbp2dIy8MERL5tA +LcgLu3KL6clJ+aTW2jgepI1D7sTepOeGd7eRSb5njKg2M7k/93v/7MipZxiVtyXH +B74YiK6jSbst5JpuYsLa/Dqryvx7Xq3n53oif892pv3euTduo1fYw8Hgh/OOYdeT +c9WCj03KA1jCSFURjdrug0kR8BPlfjqtRLXFABEBAAG0JE1TIE9wZW4gVGVjaCA8 +aW50ZXJvcEBtaWNyb3NvZnQuY29tPokBOAQTAQIAIgUCVDVtMgIbAwYLCQgHAwIG +FQgCCQoLBBYCAwECHgECF4AACgkQsCxG30F6CJO1uAf/cmL68bM8YgF/61hkaY56 +LqrppUTJH/w4fKq47Pf6KfgSLvxfNU6soi2KHYRjIvTRx3tV4vUM5n2plaQg2s8V +/Epg4FeIRTk75YwiHAzLhLnp5cdUaTvC4j4mwxoB6j9Ty+fXJwQ0MvpDhIZb9vM4 +GXw/fEQHCT4f3gx4nReeqE+FB2wVHleX9+Lpodu98JyJTKJRBRHYLqy6S+/lyp2W +aBlsI1LOqBcx1uRK24U7duIpbYwIyrx0cafSruqR2GjVdu+imkhHyUn52VbzYhq1 +af0rqYiZ1VOamVOG0By8+hVyNa1MLc1K2uWGs0o5fDe9F5/swbvLHVXI+M50Vs+m +J7kBDQRUNW0yAQgAu7DkTVj0ZQC4F7bFivAwrdby8gCakTXOl1kcK622hjRJ8nam +aZeW+eADfLRsTmdUmXgZu1YWS5Gn2ZVngC8SGPUBT071+oRETCz4uNB7IimB9QfP +++orI6o2vmnVVsq5wWCbEdNU+TCVv1zjrYev5lwckkKpjHt6o8MNoX2DFuQymSyR +eZKaqhdKmcji4Ke7OIYqwgPjch3wxzE1b5gNOR/iwxWyjjOffZPLr/VhIfIJRs86 +dSXrwjHtEh810SKDLghHM0VAdY34nyC5ZZ61yhts5HtQDFK+9mNpH1mkc4gDBlgG +266pVvknumK6lPNm/osF/cpjWmEw24ypcQIvOQARAQABiQEfBBgBAgAJBQJUNW0y +AhsMAAoJELAsRt9BegiTMBUH/0sZ6gZy7mCTSAYT+NSXLFtGC2zNUVL80SWvfgYm +k9XPVI22MrefZfQ6M01RylyxtWXjRM8UoN8SDKWPpXumzJf831f/7om5zwutaG7b +tjDPYqRKJSbAIFZu2mN+uLrNQ2SV6XK7FoV0dtcrEX9S7RICb6i19D+70+Oh/qgU +R04H1jqS29XBzqAlIzdBoA+sYAwbOIJsSL3YyNQcUv3B5+5yR/bo/L8pnUJt6iuL +nWW+mi7r8gWPHDSrcdYq1TmmlOM7CwZPgWRZzkQPSeZz52Tt7IP47eyGJ09U4PIf +FtMH1ElL2UgHoA/F9Q88e7LkztaTqE59uXWbIYyuSMJVvRU= +=sb3d +-----END PGP PUBLIC KEY BLOCK----- diff --git a/platform/vs/docker-sonic-vs/start.sh b/platform/vs/docker-sonic-vs/start.sh index 0782705bc912..876bfd835728 100755 --- a/platform/vs/docker-sonic-vs/start.sh +++ b/platform/vs/docker-sonic-vs/start.sh @@ -1,4 +1,18 @@ -#!/usr/bin/env bash +#!/bin/bash -e + +# generate configuration + +[ -d /etc/sonic ] || mkdir -p /etc/sonic + +SYSTEM_MAC_ADDRESS=$(ip link show eth0 | grep ether | awk '{print $2}') +sonic-cfggen -a '{"DEVICE_METADATA":{"localhost": {"mac": "'$SYSTEM_MAC_ADDRESS'"}}}' --print-data > /etc/sonic/init_cfg.json + +if [ -f /etc/sonic/config_db.json ]; then + sonic-cfggen -j /etc/sonic/config_db.json -j /etc/sonic/init_cfg.json --print-data > /tmp/config_db.json + mv /tmp/config_db.json /etc/sonic/config_db.json +else + sonic-cfggen -j /etc/sonic/init_cfg.json --print-data > /etc/sonic/config_db.json +fi mkdir -p /etc/swss/config.d/ @@ -16,6 +30,8 @@ mkdir -p /var/run/redis supervisorctl start redis-server +/usr/bin/configdb-load.sh + supervisorctl start syncd supervisorctl start orchagent @@ -30,8 +46,14 @@ supervisorctl start teamsyncd supervisorctl start fpmsyncd +supervisorctl start intfmgrd + +supervisorctl start vlanmgrd + +supervisorctl start zebra + # Start arp_update when VLAN exists -# VLAN=`sonic-cfggen -d -v 'VLAN.keys() | join(" ") if VLAN'` -# if [ "$VLAN" != "" ]; then -# supervisorctl start arp_update -# fi +VLAN=`sonic-cfggen -d -v 'VLAN.keys() | join(" ") if VLAN'` +if [ "$VLAN" != "" ]; then + supervisorctl start arp_update +fi diff --git a/platform/vs/docker-sonic-vs/supervisord.conf b/platform/vs/docker-sonic-vs/supervisord.conf index c91d808b9856..2526aefe3a87 100644 --- a/platform/vs/docker-sonic-vs/supervisord.conf +++ b/platform/vs/docker-sonic-vs/supervisord.conf @@ -75,9 +75,25 @@ autorestart=false stdout_logfile=syslog stderr_logfile=syslog +[program:vlanmgrd] +command=/usr/bin/vlanmgrd +priority=10 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog + +[program:intfmgrd] +command=/usr/bin/intfmgrd +priority=11 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog + [program:zebra] command=/usr/lib/quagga/zebra -A 127.0.0.1 -priority=10 +priority=12 autostart=false autorestart=false stdout_logfile=syslog @@ -85,7 +101,7 @@ stderr_logfile=syslog [program:bgpd] command=/usr/lib/quagga/bgpd -A 127.0.0.1 -F -priority=11 +priority=13 autostart=false autorestart=false stdout_logfile=syslog @@ -93,8 +109,16 @@ stderr_logfile=syslog [program:fpmsyncd] command=/usr/bin/fpmsyncd -priority=12 +priority=14 autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog + +[program:arp_update] +command=bash -c "/usr/bin/arp_update; sleep 300" +priority=15 +autostart=false +autorestart=true +stdout_logfile=syslog +stderr_logfile=syslog diff --git a/rules/asyncsnmp-py3.mk b/rules/asyncsnmp-py3.mk index a5a078e15bc3..f44d7f336534 100644 --- a/rules/asyncsnmp-py3.mk +++ b/rules/asyncsnmp-py3.mk @@ -3,5 +3,6 @@ ASYNCSNMP_PY3 = asyncsnmp-2.1.0-py3-none-any.whl $(ASYNCSNMP_PY3)_SRC_PATH = $(SRC_PATH)/sonic-snmpagent $(ASYNCSNMP_PY3)_PYTHON_VERSION = 3 -$(ASYNCSNMP_PY3)_DEPENDS += $(SWSSSDK_PY3) +# Depends on sonic-utilities so it is possible to import sonic_psu +$(ASYNCSNMP_PY3)_DEPENDS += $(SWSSSDK_PY3) $(SONIC_UTILS_PY3) SONIC_PYTHON_WHEELS += $(ASYNCSNMP_PY3) diff --git a/rules/docker-database.mk b/rules/docker-database.mk index 147b6538a098..ef77047e8431 100644 --- a/rules/docker-database.mk +++ b/rules/docker-database.mk @@ -12,3 +12,4 @@ $(DOCKER_DATABASE)_RUN_OPT += --net=host --privileged -t $(DOCKER_DATABASE)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro $(DOCKER_DATABASE)_BASE_IMAGE_FILES += redis-cli:/usr/bin/redis-cli +$(DOCKER_DATABASE)_FILES += $(CONFIGDB_LOAD_SCRIPT) diff --git a/rules/iproute2.mk b/rules/iproute2.mk new file mode 100644 index 000000000000..10d8fe4cff3d --- /dev/null +++ b/rules/iproute2.mk @@ -0,0 +1,7 @@ +# iproute2 package + +IPROUTE2_VERSION = 4.9.0-1 + +IPROUTE2 = iproute2_$(IPROUTE2_VERSION)_amd64.deb +$(IPROUTE2)_SRC_PATH = $(SRC_PATH)/iproute2 +SONIC_MAKE_DEBS += $(IPROUTE2) diff --git a/rules/linux-kernel.mk b/rules/linux-kernel.mk index 228b48a9d34b..1e7fad0fd840 100644 --- a/rules/linux-kernel.mk +++ b/rules/linux-kernel.mk @@ -2,8 +2,8 @@ KVERSION_SHORT = 3.16.0-4 KVERSION = $(KVERSION_SHORT)-amd64 -KERNEL_VERSION = 3.16.36 -KERNEL_SUBVERSION = 1+deb8u2 +KERNEL_VERSION = 3.16.43 +KERNEL_SUBVERSION = 2+deb8u5 export KVERSION_SHORT KVERSION KERNEL_VERSION KERNEL_SUBVERSION diff --git a/rules/scripts.mk b/rules/scripts.mk new file mode 100644 index 000000000000..fbefdd68d2cd --- /dev/null +++ b/rules/scripts.mk @@ -0,0 +1,11 @@ + +ARP_UPDATE_SCRIPT = arp_update +$(ARP_UPDATE_SCRIPT)_PATH = files/scripts + +CONFIGDB_LOAD_SCRIPT = configdb-load.sh +$(CONFIGDB_LOAD_SCRIPT)_PATH = files/scripts + +SONIC_COPY_FILES += $(CONFIGDB_LOAD_SCRIPT) \ + $(ARP_UPDATE_SCRIPT) + + diff --git a/rules/sonic-utilities.mk b/rules/sonic-utilities.mk index 7a935ba70ede..0dae94d8aa70 100644 --- a/rules/sonic-utilities.mk +++ b/rules/sonic-utilities.mk @@ -4,3 +4,11 @@ SONIC_UTILS = python-sonic-utilities_1.1-1_all.deb $(SONIC_UTILS)_SRC_PATH = $(SRC_PATH)/sonic-utilities $(SONIC_UTILS)_WHEEL_DEPENDS = $(SONIC_CONFIG_ENGINE) SONIC_PYTHON_STDEB_DEBS += $(SONIC_UTILS) + +# Build sonic-utilities into python3 wheel, so we can use PSU code +# Note: _DEPENDS macro is not defined +SONIC_UTILS_PY3 = sonic_utilities-1.1-py3-none-any.whl +$(SONIC_UTILS_PY3)_SRC_PATH = $(SRC_PATH)/sonic-utilities +$(SONIC_UTILS_PY3)_PYTHON_VERSION = 3 +$(SONIC_UTILS_PY3)_TEST = n +SONIC_PYTHON_WHEELS += $(SONIC_UTILS_PY3) diff --git a/rules/tacacs.mk b/rules/tacacs.mk new file mode 100644 index 000000000000..e31f52d9ab5d --- /dev/null +++ b/rules/tacacs.mk @@ -0,0 +1,29 @@ +# libpam-tacplus packages + +PAM_TACPLUS_VERSION = 1.4.1-1 + +export PAM_TACPLUS_VERSION + +LIBPAM_TACPLUS = libpam-tacplus_$(PAM_TACPLUS_VERSION)_amd64.deb +$(LIBPAM_TACPLUS)_RDEPENDS += $(LIBTAC2) +$(LIBPAM_TACPLUS)_SRC_PATH = $(SRC_PATH)/tacacs/pam +SONIC_MAKE_DEBS += $(LIBPAM_TACPLUS) + +LIBTAC_DEV = libtac-dev_$(PAM_TACPLUS_VERSION)_amd64.deb +$(LIBTAC_DEV)_DEPENDS += $(LIBTAC2) +$(eval $(call add_derived_package,$(LIBTAC2),$(LIBTAC_DEV))) + +LIBTAC2 = libtac2_$(PAM_TACPLUS_VERSION)_amd64.deb +$(eval $(call add_extra_package,$(LIBPAM_TACPLUS),$(LIBTAC2))) + + +# libnss-tacplus packages +NSS_TACPLUS_VERSION = 1.0.4-1 + +export NSS_TACPLUS_VERSION + +LIBNSS_TACPLUS = libnss-tacplus_$(NSS_TACPLUS_VERSION)_amd64.deb +$(LIBNSS_TACPLUS)_DEPENDS += $(LIBTAC_DEV) +$(LIBNSS_TACPLUS)_RDEPENDS += $(LIBTAC2) +$(LIBNSS_TACPLUS)_SRC_PATH = $(SRC_PATH)/tacacs/nss +SONIC_MAKE_DEBS += $(LIBNSS_TACPLUS) diff --git a/slave.mk b/slave.mk index 71cee41e3d0a..8ec6832bd687 100644 --- a/slave.mk +++ b/slave.mk @@ -306,7 +306,7 @@ $(addprefix $(PYTHON_WHEELS_PATH)/, $(SONIC_PYTHON_WHEELS)) : $(PYTHON_WHEELS_PA pushd $($*_SRC_PATH) $(LOG) # apply series of patches if exist if [ -f ../$(notdir $($*_SRC_PATH)).patch/series ]; then QUILT_PATCHES=../$(notdir $($*_SRC_PATH)).patch quilt push -a; fi - python$($*_PYTHON_VERSION) setup.py test $(LOG) + [ "$($*_TEST)" = "n" ] || python$($*_PYTHON_VERSION) setup.py test $(LOG) python$($*_PYTHON_VERSION) setup.py bdist_wheel $(LOG) # clean up if [ -f ../$(notdir $($*_SRC_PATH)).patch/series ]; then quilt pop -a -f; fi @@ -336,7 +336,7 @@ $(SONIC_INSTALL_WHEELS) : $(PYTHON_WHEELS_PATH)/%-install : .platform $$(addsuff # start docker daemon docker-start : - @sudo service docker start &> /dev/null && sleep 1 + @sudo service docker status &> /dev/null || ( sudo service docker start &> /dev/null && sleep 1 ) # targets for building simple docker images that do not depend on any debian packages $(addprefix $(TARGET_PATH)/, $(SONIC_SIMPLE_DOCKER_IMAGES)) : $(TARGET_PATH)/%.gz : .platform docker-start $$(addsuffix -load,$$(addprefix $(TARGET_PATH)/,$$($$*.gz_LOAD_DOCKERS))) @@ -391,7 +391,9 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ $(LINUX_KERNEL) \ $(IGB_DRIVER) \ $(SONIC_DEVICE_DATA) \ - $(SONIC_UTILS)) \ + $(SONIC_UTILS) \ + $(LIBPAM_TACPLUS) \ + $(LIBNSS_TACPLUS)) \ $$(addprefix $(TARGET_PATH)/,$$($$*_DOCKERS)) \ $$(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_CONFIG_ENGINE)) $(HEADER) diff --git a/sonic-slave/Dockerfile b/sonic-slave/Dockerfile index 1e9a2978389f..ea40a4ce4c65 100644 --- a/sonic-slave/Dockerfile +++ b/sonic-slave/Dockerfile @@ -168,10 +168,11 @@ RUN apt-get update && apt-get install -y \ cppcheck \ clang \ pylint \ - python-pytest \ gcovr \ python-pytest=2.6.3* \ + python3-pytest=2.6.3* \ python-pytest-cov \ + python3-pytest-cov \ python-parse \ # For snmpd libmysqlclient-dev \ @@ -200,13 +201,27 @@ RUN apt-get update && apt-get install -y \ python-netaddr \ python-ipaddr \ python-yaml \ +# For sonic utilities + python3-netaddr \ # For lockfile procmail \ # For gtest libgtest-dev \ cmake \ +# For pam_tacplus build + autoconf-archive \ # For python-based swsscommon - swig3.0 + swig3.0 \ +# For iproute2 + cm-super-minimal \ + libatm1-dev \ + libelf-dev \ + libmnl-dev \ + libselinux1-dev \ + linuxdoc-tools \ + lynx \ + texlive-latex-extra \ + texlive-latex-recommended # For linux build RUN apt-get -y build-dep linux diff --git a/src/iproute2/Makefile b/src/iproute2/Makefile new file mode 100644 index 000000000000..0181c9ca6d31 --- /dev/null +++ b/src/iproute2/Makefile @@ -0,0 +1,20 @@ +SHELL = /bin/bash +.ONESHELL: +.SHELLFLAGS += -e + +IPROUTE2_VERSION = 4.9.0 +IPROUTE2_VERSION_FULL = $(IPROUTE2_VERSION)-1 + +MAIN_TARGET = iproute2_$(IPROUTE2_VERSION_FULL)_amd64.deb + +$(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : + wget -O iproute2_$(IPROUTE2_VERSION).orig.tar.xz -N "https://sonicstorage.blob.core.windows.net/packages/iproute2_4.9.0.orig.tar.xz?sv=2015-04-05&sr=b&sig=9nvybd1xkXyRQbaG6Fy6wBazPA8IbZV0AO41GWXPEP8%3D&se=2154-10-23T11%3A59%3A00Z&sp=r" + wget -O iproute2_$(IPROUTE2_VERSION_FULL).dsc -N "https://sonicstorage.blob.core.windows.net/packages/iproute2_4.9.0-1.dsc?sv=2015-04-05&sr=b&sig=m6FcMH9dOh8ggipBgOsONiXvDxoi6bfUO%2BxvidsMNMQ%3D&se=2154-10-23T11%3A59%3A53Z&sp=r" + wget -O iproute2_$(IPROUTE2_VERSION_FULL).debian.tar.xz -N "https://sonicstorage.blob.core.windows.net/packages/iproute2_4.9.0-1.debian.tar.xz?sv=2015-04-05&sr=b&sig=U5NFuwG5C3vZXlUUNvoPMnKDtMKk66zbweA9rQYbEVY%3D&se=2154-10-23T12%3A00%3A15Z&sp=r" + dpkg-source -x iproute2_$(IPROUTE2_VERSION_FULL).dsc + + pushd iproute2-$(IPROUTE2_VERSION) + dpkg-buildpackage -us -uc -b -j$(SONIC_CONFIG_MAKE_JOBS) + popd + + mv $* $(DEST)/ diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index 826997063349..f33bd11f0b93 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -298,7 +298,8 @@ def parse_meta(meta, hname): return syslog_servers, dhcp_servers, ntp_servers, mgmt_routes, erspan_dst, deployment_id def parse_deviceinfo(meta, hwsku): - ethernet_interfaces = {} + port_speeds = {} + port_descriptions = {} for device_info in meta.findall(str(QName(ns, "DeviceInfo"))): dev_sku = device_info.find(str(QName(ns, "HwSku"))).text if dev_sku == hwsku: @@ -306,8 +307,11 @@ def parse_deviceinfo(meta, hwsku): for interface in interfaces.findall(str(QName(ns1, "EthernetInterface"))): alias = interface.find(str(QName(ns, "InterfaceName"))).text speed = interface.find(str(QName(ns, "Speed"))).text - ethernet_interfaces[port_alias_map.get(alias, alias)] = speed - return ethernet_interfaces + desc = interface.find(str(QName(ns, "Description"))) + if desc != None: + port_descriptions[port_alias_map.get(alias, alias)] = desc.text + port_speeds[port_alias_map.get(alias, alias)] = speed + return port_speeds, port_descriptions def parse_xml(filename, platform=None, port_config_file=None): root = ET.parse(filename).getroot() @@ -330,6 +334,7 @@ def parse_xml(filename, platform=None, port_config_file=None): devices = None hostname = None port_speeds = {} + port_descriptions = {} syslog_servers = [] dhcp_servers = [] ntp_servers = [] @@ -360,7 +365,7 @@ def parse_xml(filename, platform=None, port_config_file=None): elif child.tag == str(QName(ns, "MetadataDeclaration")): (syslog_servers, dhcp_servers, ntp_servers, mgmt_routes, erspan_dst, deployment_id) = parse_meta(child, hostname) elif child.tag == str(QName(ns, "DeviceInfos")): - port_speeds = parse_deviceinfo(child, hwsku) + (port_speeds, port_descriptions) = parse_deviceinfo(child, hwsku) results = {} results['DEVICE_METADATA'] = {'localhost': { @@ -395,6 +400,9 @@ def parse_xml(filename, platform=None, port_config_file=None): for port_name in port_speeds: ports.setdefault(port_name, {})['speed'] = port_speeds[port_name] + for port_name in port_descriptions: + ports.setdefault(port_name, {})['description'] = port_descriptions[port_name] + results['PORT'] = ports results['PORTCHANNEL'] = pcs results['VLAN'] = vlans diff --git a/src/sonic-config-engine/sonic-cfggen b/src/sonic-config-engine/sonic-cfggen index 9f1323dab2eb..a5727d38b96f 100755 --- a/src/sonic-config-engine/sonic-cfggen +++ b/src/sonic-config-engine/sonic-cfggen @@ -135,6 +135,7 @@ def main(): parser.add_argument("-j", "--json", help="json file that contains additional variables", action='append', default=[]) parser.add_argument("-a", "--additional-data", help="addition data, in json string") parser.add_argument("-d", "--from-db", help="read config from configdb", action='store_true') + parser.add_argument("-s", "--redis-unix-sock-file", help="unix sock file for redis connection") group = parser.add_mutually_exclusive_group() group.add_argument("-t", "--template", help="render the data with the template file") group.add_argument("-v", "--var", help="print the value of a variable, support jinja2 expression") @@ -151,6 +152,10 @@ def main(): if platform_info != None: data['platform'] = platform_info + db_kwargs = {} + if args.redis_unix_sock_file != None: + db_kwargs['unix_socket_path'] = args.redis_unix_sock_file + if args.minigraph != None: minigraph = args.minigraph if data.has_key('platform'): @@ -180,7 +185,7 @@ def main(): deep_update(data, json.loads(args.additional_data)) if args.from_db: - configdb = ConfigDBConnector() + configdb = ConfigDBConnector(**db_kwargs) configdb.connect() deep_update(data, FormatConverter.db_to_output(configdb.get_config())) @@ -203,9 +208,9 @@ def main(): print json.dumps(FormatConverter.to_serialized(data[args.var_json]), indent=4, cls=minigraph_encoder) if args.write_to_db: - configdb = ConfigDBConnector() + configdb = ConfigDBConnector(**db_kwargs) configdb.connect(False) - configdb.set_config(FormatConverter.output_to_db(data)) + configdb.mod_config(FormatConverter.output_to_db(data)) if args.print_data: print json.dumps(FormatConverter.to_serialized(data), indent=4, cls=minigraph_encoder) diff --git a/src/sonic-config-engine/tests/sample_output/lldpd.conf b/src/sonic-config-engine/tests/sample_output/lldpd.conf index 0328385cf307..d906f909bc7d 100644 --- a/src/sonic-config-engine/tests/sample_output/lldpd.conf +++ b/src/sonic-config-engine/tests/sample_output/lldpd.conf @@ -1,3 +1,4 @@ +configure ports eth0 lldp portidsubtype local eth0 configure ports Ethernet116 lldp portidsubtype local fortyGigE0/116 description ARISTA02T1:Ethernet1/1 configure ports Ethernet124 lldp portidsubtype local fortyGigE0/124 description ARISTA04T1:Ethernet1/1 configure ports Ethernet112 lldp portidsubtype local fortyGigE0/112 description ARISTA01T1:Ethernet1/1 diff --git a/src/sonic-config-engine/tests/sample_output/msn27.32ports.json b/src/sonic-config-engine/tests/sample_output/msn27.32ports.json index c65ebb847d7b..a3cff0f0f0d5 100644 --- a/src/sonic-config-engine/tests/sample_output/msn27.32ports.json +++ b/src/sonic-config-engine/tests/sample_output/msn27.32ports.json @@ -27,7 +27,7 @@ "BUFFER_PROFILE_TABLE:ingress_lossless_profile": { "pool":"[BUFFER_POOL_TABLE:ingress_lossless_pool]", "size":"0", - "dynamic_th":"7" + "dynamic_th":"1" }, "OP": "SET" }, @@ -42,7 +42,7 @@ { "BUFFER_PROFILE_TABLE:egress_lossless_profile": { "pool":"[BUFFER_POOL_TABLE:egress_lossless_pool]", - "size":"1518", + "size":"0", "dynamic_th":"7" }, "OP": "SET" @@ -59,7 +59,7 @@ "BUFFER_PROFILE_TABLE:pg_lossy_profile": { "pool":"[BUFFER_POOL_TABLE:ingress_lossy_pool]", "size":"0", - "dynamic_th":"3" + "dynamic_th":"7" }, "OP": "SET" }, @@ -75,7 +75,7 @@ "BUFFER_PROFILE_TABLE:q_lossy_profile": { "pool":"[BUFFER_POOL_TABLE:egress_lossy_pool]", "size":"0", - "dynamic_th":"1" + "dynamic_th":"7" }, "OP": "SET" }, diff --git a/src/sonic-config-engine/tests/sample_output/ports.json b/src/sonic-config-engine/tests/sample_output/ports.json new file mode 100644 index 000000000000..216627ef34cd --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/ports.json @@ -0,0 +1,30 @@ +[ + { + "PORT_TABLE:Ethernet8": { + "speed": "40000", + "description": "Interface description" + }, + "OP": "SET" + }, + { + "PORT_TABLE:Ethernet0": { + "speed": "10000", + "description": "" + }, + "OP": "SET" + }, + { + "PORT_TABLE:Ethernet4": { + "speed": "25000", + "description": "" + }, + "OP": "SET" + }, + { + "PORT_TABLE:Ethernet12": { + "speed": "1000000", + "description": "Interface description" + }, + "OP": "SET" + }, +] diff --git a/src/sonic-config-engine/tests/simple-sample-graph.xml b/src/sonic-config-engine/tests/simple-sample-graph.xml index 89f53af83e41..d3bc25272282 100644 --- a/src/sonic-config-engine/tests/simple-sample-graph.xml +++ b/src/sonic-config-engine/tests/simple-sample-graph.xml @@ -243,6 +243,7 @@ 0 0 40000 + Interface description DeviceInterface @@ -256,6 +257,7 @@ 0 0 1000000 + Interface description true diff --git a/src/sonic-config-engine/tests/test_cfggen.py b/src/sonic-config-engine/tests/test_cfggen.py index 47cc006f4662..2eee6fe331c8 100644 --- a/src/sonic-config-engine/tests/test_cfggen.py +++ b/src/sonic-config-engine/tests/test_cfggen.py @@ -138,4 +138,4 @@ def test_minigraph_deployment_id(self): def test_minigraph_ethernet_interfaces(self): argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v "PORT[\'Ethernet8\']"' output = self.run_script(argument) - self.assertEqual(output.strip(), "{'alias': 'fortyGigE0/8', 'lanes': '37,38,39,40', 'speed': '40000'}") + self.assertEqual(output.strip(), "{'alias': 'fortyGigE0/8', 'lanes': '37,38,39,40', 'description': 'Interface description', 'speed': '40000'}") diff --git a/src/sonic-config-engine/tests/test_j2files.py b/src/sonic-config-engine/tests/test_j2files.py index d1cc0d2a3296..ce96ab425c82 100644 --- a/src/sonic-config-engine/tests/test_j2files.py +++ b/src/sonic-config-engine/tests/test_j2files.py @@ -9,6 +9,7 @@ class TestJ2Files(TestCase): def setUp(self): self.test_dir = os.path.dirname(os.path.realpath(__file__)) self.script_file = os.path.join(self.test_dir, '..', 'sonic-cfggen') + self.simple_minigraph = os.path.join(self.test_dir, 'simple-sample-graph.xml') self.t0_minigraph = os.path.join(self.test_dir, 't0-sample-graph.xml') self.pc_minigraph = os.path.join(self.test_dir, 'pc-test-graph.xml') self.t0_port_config = os.path.join(self.test_dir, 't0-sample-port-config.ini') @@ -33,6 +34,12 @@ def test_alias_map(self): data = json.loads(output) self.assertEqual(data["Ethernet4"], "fortyGigE0/4") + def test_ports_json(self): + ports_template = os.path.join(self.test_dir, '..', '..', '..', 'dockers', 'docker-orchagent', 'ports.json.j2') + argument = '-m ' + self.simple_minigraph + ' -p ' + self.t0_port_config + ' -t ' + ports_template + ' > ' + self.output_file + self.run_script(argument) + self.assertTrue(filecmp.cmp(os.path.join(self.test_dir, 'sample_output', 'ports.json'), self.output_file)) + def test_lldp(self): lldpd_conf_template = os.path.join(self.test_dir, '..', '..', '..', 'dockers', 'docker-lldp-sv2', 'lldpd.conf.j2') argument = '-m ' + self.t0_minigraph + ' -p ' + self.t0_port_config + ' -t ' + lldpd_conf_template + ' > ' + self.output_file diff --git a/src/sonic-linux-kernel b/src/sonic-linux-kernel index b386d52bd68b..ff5a3b588cc7 160000 --- a/src/sonic-linux-kernel +++ b/src/sonic-linux-kernel @@ -1 +1 @@ -Subproject commit b386d52bd68bdc5facbd837e265f49a8350e14a1 +Subproject commit ff5a3b588cc7dbd763fb13c1125710134c8cdd12 diff --git a/src/sonic-py-swsssdk b/src/sonic-py-swsssdk index 674fb107dfb8..1c7a6b449644 160000 --- a/src/sonic-py-swsssdk +++ b/src/sonic-py-swsssdk @@ -1 +1 @@ -Subproject commit 674fb107dfb8e45b23a55e3e7be34e39d5630942 +Subproject commit 1c7a6b4496440a8a9e7e2ab314564ce8e26aa378 diff --git a/src/sonic-sairedis b/src/sonic-sairedis index 67d998bb7e1b..ce8028239b25 160000 --- a/src/sonic-sairedis +++ b/src/sonic-sairedis @@ -1 +1 @@ -Subproject commit 67d998bb7e1bf2845cc9238adc438d1f215750c0 +Subproject commit ce8028239b2595e8f42c8c1af573a5444c617513 diff --git a/src/sonic-swss b/src/sonic-swss index c9446922a8a4..5aabe44417c4 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit c9446922a8a4e9fb760d0d4b77760826fbbd1974 +Subproject commit 5aabe44417c4d31e39a5cfb91b36f7338cebfe81 diff --git a/src/sonic-swss-common b/src/sonic-swss-common index a67ee684ed33..cbc0e1a858ca 160000 --- a/src/sonic-swss-common +++ b/src/sonic-swss-common @@ -1 +1 @@ -Subproject commit a67ee684ed33083f61df83cd1ba9c047e5ed8b68 +Subproject commit cbc0e1a858cad81835c457bb98abc28af86523db diff --git a/src/sonic-utilities b/src/sonic-utilities index e87bb97760a4..cb8538962815 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit e87bb97760a4cf069da51b2a0da732f7a40f3215 +Subproject commit cb8538962815ea82665a4d4b851d50ea0793811d diff --git a/src/tacacs/nss/0001-Modify-user-map-profile.patch b/src/tacacs/nss/0001-Modify-user-map-profile.patch new file mode 100644 index 000000000000..75d037977de4 --- /dev/null +++ b/src/tacacs/nss/0001-Modify-user-map-profile.patch @@ -0,0 +1,1459 @@ +From 43096cf9813d6def1d1f8f1d8a0c122466c8c06b Mon Sep 17 00:00:00 2001 +From: Liuqu +Date: Mon, 9 Oct 2017 02:44:37 -0700 +Subject: [PATCH] Modify user map profile + +* Removed dependence from libtacplus_map and libaudit +* Removed NSS entry point for getpwuid() +* Modified user map profile, create local user account for each TACACS+ user + which not found in local. +* Added "many_to_one" mode, create one local user for many TACACS+ users which + has the same privilege. +* Modified configuration parse and file to adapt to the new user map profile. +--- + Makefile.am | 4 +- + Makefile.in | 2 +- + configure.ac | 2 +- + debian/changelog | 11 + + debian/control | 11 +- + debian/libnss-tacplus.symbols | 1 - + nss_tacplus.c | 1004 +++++++++++++++++++---------------------- + tacplus_nss.conf | 91 ++-- + 8 files changed, 518 insertions(+), 608 deletions(-) + +diff --git a/Makefile.am b/Makefile.am +index 293951e..b33c455 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -19,7 +19,7 @@ nss_tacplus.h + libnss_tacplus_la_CFLAGS = $(AM_CFLAGS) + # Version 2.0 because that's the NSS module version, and they must match + libnss_tacplus_la_LDFLAGS = -module -version-info 2:0:0 -shared +-libnss_tacplus_la_LIBADD = -ltacplus_map -ltac -laudit ++libnss_tacplus_la_LIBADD = -ltac + + + EXTRA_DIST = tacplus_nss.conf README ChangeLog +@@ -52,7 +52,7 @@ install-data-hook: + rm -f $(DESTDIR)$(libdir)/libnss_tacplus.so $(DESTDIR)$(libdir)/libnss_tacplus.so.2.0.0 + $(mkinstalldirs) $(DESTDIR)$(libdir) $(DESTDIR)$(sysconfdir) + cd .libs && $(INSTALL_PROGRAM) libnss_tacplus.so $(DESTDIR)$(libdir)/$(NSS_TACPLUS_LIBC_VERSIONED) +- $(STRIP) --keep-symbol=_nss_tacplus_getpwnam_r --keep-symbol=_nss_tacplus_getpwuid_r $(DESTDIR)$(libdir)/$(NSS_TACPLUS_LIBC_VERSIONED) ++ $(STRIP) --keep-symbol=_nss_tacplus_getpwnam_r $(DESTDIR)$(libdir)/$(NSS_TACPLUS_LIBC_VERSIONED) + cd $(DESTDIR)$(libdir); ln -sf $(NSS_TACPLUS_LIBC_VERSIONED) $(NSS_TACPLUS_NSS_VERSIONED) + ${INSTALL} -m 644 tacplus_nss.conf $(DESTDIR)$(sysconfdir) + +diff --git a/Makefile.in b/Makefile.in +index 0d18ce7..5159b37 100644 +--- a/Makefile.in ++++ b/Makefile.in +@@ -273,7 +273,7 @@ nss_tacplus.h + libnss_tacplus_la_CFLAGS = $(AM_CFLAGS) + # Version 2.0 because that's the NSS module version, and they must match + libnss_tacplus_la_LDFLAGS = -module -version-info 2:0:0 -shared +-libnss_tacplus_la_LIBADD = -ltacplus_map -ltac -laudit ++libnss_tacplus_la_LIBADD = -ltac + EXTRA_DIST = tacplus_nss.conf README ChangeLog + MAINTAINERCLEANFILES = Makefile.in config.h.in configure aclocal.m4 \ + config/config.guess config/config.sub config/depcomp \ +diff --git a/configure.ac b/configure.ac +index 42fb8f9..8c04668 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -53,7 +53,7 @@ dnl -------------------------------------------------------------------- + dnl Checks for header files. + AC_HEADER_STDC + AC_CHECK_HEADERS([nss.h fcntl.h stdlib.h string.h strings.h sys/socket.h sys/time.h syslog.h unistd.h]) +-AC_CHECK_HEADERS([tacplus/libtac.h]) ++AC_CHECK_HEADERS([libtac/libtac.h]) + + dnl -------------------------------------------------------------------- + dnl Checks for typedefs, structures, and compiler characteristics. +diff --git a/debian/changelog b/debian/changelog +index b24ac24..d4103ed 100644 +--- a/debian/changelog ++++ b/debian/changelog +@@ -1,3 +1,14 @@ ++libnss-tacplus (1.0.4-1) unstable; urgency=low ++ * Removed dependence from libtacplus_map and libaudit ++ * Removed NSS entry point for getpwuid() ++ * Modified user map profile, create local user account for each TACACS+ user ++ which not found in local. ++ * Added "many_to_one" mode, create one local user for many TACACS+ users which ++ has the same privilege. ++ * Modified configuration parse and file to adapt to the new user map profile. ++ ++ -- Chenchen Qi Tue, 10 Oct 2017 14:23:44 +0800 ++ + libnss-tacplus (1.0.3-2) unstable; urgency=low + * Fixed package remove to clean up plugin entries in nsswitch.conf + * New Disabled: added user_homedir config variable to allow per-user +diff --git a/debian/control b/debian/control +index ea65d0b..bdc888f 100644 +--- a/debian/control ++++ b/debian/control +@@ -1,17 +1,14 @@ + Source: libnss-tacplus + Priority: optional + Maintainer: Dave Olson +-Build-Depends: debhelper (>= 9), autotools-dev, libtac-dev (>= 1.4.1~), +- libtacplus-map-dev, libaudit-dev, autoconf, libpam-tacplus-dev, +- dpkg-dev (>= 1.16.1), git ++Build-Depends: debhelper (>= 9), autotools-dev, libtac-dev (>= 1.4.1~) + Section: libs + Standards-Version: 3.9.6 + Homepage: http://www.cumulusnetworks.com + + Package: libnss-tacplus + Architecture: any +-Depends: ${shlibs:Depends}, ${misc:Depends}, libtac2 (>= 1.4.1~), +- libtacplus-map1, libaudit1 ++Depends: ${shlibs:Depends}, ${misc:Depends}, libtac2 (>= 1.4.1~) + Description: NSS module for TACACS+ authentication without local passwd entry +- Performs getpwname and getpwuid lookups via NSS for users logged in via +- tacacs authentication, and mapping done with libtacplus_map ++ Performs getpwname lookups via NSS for users logged in via ++ tacacs authentication +diff --git a/debian/libnss-tacplus.symbols b/debian/libnss-tacplus.symbols +index 2bf9b88..f476e7d 100644 +--- a/debian/libnss-tacplus.symbols ++++ b/debian/libnss-tacplus.symbols +@@ -1,3 +1,2 @@ + libnss_tacplus.so.2 libnss-tacplus #MINVER# + _nss_tacplus_getpwnam_r@Base 1.0.1 +- _nss_tacplus_getpwuid_r@Base 1.0.1 +diff --git a/nss_tacplus.c b/nss_tacplus.c +index 79e62b9..ecfa0b0 100644 +--- a/nss_tacplus.c ++++ b/nss_tacplus.c +@@ -1,7 +1,9 @@ + /* +- * Copyright (C) 2014, 2015, 2016, 2017 Cumulus Networks, Inc. ++ * Copyright (C) 2014, 2015, 2016 Cumulus Networks, Inc. ++ * Copyright (C) 2017 Chenchen Qi + * All rights reserved. + * Author: Dave Olson ++ * Chenchen Qi + * + * 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 +@@ -18,15 +20,9 @@ + */ + + /* +- * This plugin implements getpwnam_r for NSS over TACACS+ +- * and implements getpwuid_r for UIDs if and only if a mapped +- * TACACS+ user is currently logged in (libtacplus_map) +- * This means that if you do, e.g.: ls -ld ~tacacs15, you will +- * sometimes get a mapped username, and other times get tacacs15, +- * depending on whether a mapped user is logged in or not. ++ * This plugin implements getpwnam_r for NSS over TACACS+. + */ + +- + #include + #include + #include +@@ -35,18 +31,18 @@ + #include + #include + #include ++#include + #include +-#include +-#include +-#include + +-#include +-#include ++#include + +-#include "nss_tacplus.h" ++#define MIN_TACACS_USER_PRIV (1) ++#define MAX_TACACS_USER_PRIV (15) + + static const char *nssname = "nss_tacplus"; /* for syslogs */ + static const char *config_file = "/etc/tacplus_nss.conf"; ++static const char *user_conf = "/etc/tacplus_user"; ++static const char *user_conf_tmp = "/tmp/tacplus_user_tmp"; + + /* + * pwbuf is used to reduce number of arguments passed around; the strings in +@@ -63,255 +59,239 @@ struct pwbuf { + typedef struct { + struct addrinfo *addr; + char *key; +-} tacplus_server_t; ++ int timeout; ++}tacplus_server_t; ++ ++typedef struct { ++ char *info; ++ int gid; ++ char *secondary_grp; ++ char *shell; ++}useradd_info_t; + + /* set from configuration file parsing */ + static tacplus_server_t tac_srv[TAC_PLUS_MAXSERVERS]; +-static int tac_srv_no, tac_key_no; +-static char tac_service[] = "shell"; +-static char tac_protocol[] = "ssh"; +-static char tac_rhost[INET6_ADDRSTRLEN]; +-static char vrfname[64]; +-static char *exclude_users; +-static uid_t min_uid = ~0U; /* largest possible */ +-static int debug; +-uint16_t use_tachome; +-static int conf_parsed = 0; +- +-static void get_remote_addr(void); +- +-#define MAX_INCL 8 /* max config level nesting */ +- +-/* reset all config variables when we are going to re-parse */ +-static void +-reset_config(void) +-{ +- int i, nservers; ++static int tac_srv_no; ++static useradd_info_t useradd_grp_list[MAX_TACACS_USER_PRIV + 1]; + +- /* reset the config variables that we use, freeing memory where needed */ +- nservers = tac_srv_no; +- tac_srv_no = 0; +- tac_key_no = 0; +- vrfname[0] = '\0'; +- if(exclude_users) { +- (void)free(exclude_users); +- exclude_users = NULL; +- } +- debug = 0; +- use_tachome = 0; +- tac_timeout = 0; +- min_uid = ~0U; +- +- for(i = 0; i < nservers; i++) { +- if(tac_srv[i].key) { +- free(tac_srv[i].key); +- tac_srv[i].key = NULL; +- } +- tac_srv[i].addr = NULL; +- } +-} ++static char *tac_service = "shell"; ++static char *tac_protocol = "ssh"; ++static bool debug = false; ++static bool many_to_one = false; + +-static int nss_tacplus_config(int *errnop, const char *cfile, int top) ++static int parse_tac_server(char *srv_buf) + { +- FILE *conf; +- char lbuf[256]; +- static struct stat lastconf[MAX_INCL]; +- static char *cfilelist[MAX_INCL]; +- struct stat st, *lst; +- +- if(top > MAX_INCL) { +- syslog(LOG_NOTICE, "%s: Config file include depth > %d, ignoring %s", +- nssname, MAX_INCL, cfile); +- return 1; +- } +- +- lst = &lastconf[top-1]; +- if(conf_parsed && top == 1) { +- /* +- * check to see if the config file(s) have changed since last time, +- * in case we are part of a long-lived daemon. If any changed, +- * reparse. If not, return the appropriate status (err or OK) +- * This is somewhat complicated by the include file mechanism. +- * When we have nested includes, we have to check all the config +- * files we saw previously, not just the top level config file. +- */ +- int i; +- for(i=0; i < MAX_INCL; i++) { +- struct stat *cst; +- cst = &lastconf[i]; +- if(!cst->st_ino || !cfilelist[i]) /* end of files */ +- return conf_parsed == 2 ? 0 : 1; +- if (stat(cfilelist[i], &st) || st.st_ino != cst->st_ino || +- st.st_mtime != cst->st_mtime || st.st_ctime != cst->st_ctime) +- break; /* found removed or different file, so re-parse */ +- } +- reset_config(); +- syslog(LOG_NOTICE, "%s: Configuration file(s) have changed, re-initializing", +- nssname); +- } +- +- /* don't check for failures, we'll just skip, don't want to error out */ +- cfilelist[top-1] = strdup(cfile); +- conf = fopen(cfile, "r"); +- if(conf == NULL) { +- *errnop = errno; +- if(!conf_parsed && debug) /* debug because privileges may not allow */ +- syslog(LOG_DEBUG, "%s: can't open config file %s: %m", +- nssname, cfile); +- return 1; +- } +- if (fstat(fileno(conf), lst) != 0) +- memset(lst, 0, sizeof *lst); /* avoid stale data, no warning */ +- +- while(fgets(lbuf, sizeof lbuf, conf)) { +- if(*lbuf == '#' || isspace(*lbuf)) +- continue; /* skip comments, white space lines, etc. */ +- strtok(lbuf, " \t\n\r\f"); /* terminate buffer at first whitespace */ +- if(!strncmp(lbuf, "include=", 8)) { +- /* +- * allow include files, useful for centralizing tacacs +- * server IP address and secret. When running non-privileged, +- * may not be able to read one or more config files. +- */ +- if(lbuf[8]) +- (void)nss_tacplus_config(errnop, &lbuf[8], top+1); +- } +- else if(!strncmp(lbuf, "debug=", 6)) +- debug = strtoul(lbuf+6, NULL, 0); +- else if (!strncmp (lbuf, "user_homedir=", 13)) +- use_tachome = (uint16_t)strtoul(lbuf+13, NULL, 0); +- else if (!strncmp (lbuf, "timeout=", 8)) { +- tac_timeout = (int)strtoul(lbuf+8, NULL, 0); +- if (tac_timeout < 0) /* explict neg values disable poll() use */ +- tac_timeout = 0; +- else /* poll() only used if timeout is explictly set */ +- tac_readtimeout_enable = 1; +- } +- /* +- * This next group is here to prevent a warning in the +- * final "else" case. We don't need them, but if there +- * is a common included file, we might see them. +- */ +- else if(!strncmp(lbuf, "service=", 8) || +- !strncmp(lbuf, "protocol=", 9) || +- !strncmp(lbuf, "login=", 6)) +- ; +- else if(!strncmp(lbuf, "secret=", 7)) { +- int i; +- /* no need to complain if too many on this one */ +- if(tac_key_no < TAC_PLUS_MAXSERVERS) { +- if((tac_srv[tac_key_no].key = strdup(lbuf+7))) +- tac_key_no++; +- else +- syslog(LOG_ERR, "%s: unable to copy server secret %s", +- nssname, lbuf+7); +- } +- /* handle case where 'secret=' was given after a 'server=' +- * parameter, fill in the current secret */ +- for(i = tac_srv_no-1; i >= 0; i--) { +- if (tac_srv[i].key) +- continue; +- tac_srv[i].key = strdup(lbuf+7); +- } +- } +- else if(!strncmp(lbuf, "exclude_users=", 14)) { +- /* +- * Don't lookup users in this comma-separated list for both +- * robustness and performnce. Typically root and other commonly +- * used local users. If set, we also look up the uids +- * locally, and won't do remote lookup on those uids either. +- */ +- exclude_users = strdup(lbuf+14); +- } +- else if(!strncmp(lbuf, "min_uid=", 8)) { +- /* +- * Don't lookup uids that are local, typically set to either +- * 0 or smallest always local user's uid +- */ +- unsigned long uid; +- char *valid; +- uid = strtoul(lbuf+8, &valid, 0); +- if (valid > (lbuf+8)) +- min_uid = (uid_t)uid; +- } +- else if(!strncmp(lbuf, "vrf=", 4)) +- strncpy(vrfname, lbuf + 4, sizeof(vrfname)); +- else if(!strncmp(lbuf, "server=", 7)) { +- if(tac_srv_no < TAC_PLUS_MAXSERVERS) { +- struct addrinfo hints, *servers, *server; ++ char *token; ++ char delim[] = " ,\t\n\r\f"; ++ ++ token = strsep(&srv_buf, delim); ++ while(token) { ++ if('\0' != token) { ++ if(!strncmp(token, "server=", 7)) { ++ struct addrinfo hints, *server; + int rv; +- char *port, server_buf[sizeof lbuf]; ++ char *srv, *port; + + memset(&hints, 0, sizeof hints); +- hints.ai_family = AF_UNSPEC; /* use IPv4 or IPv6, whichever */ ++ hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + +- strcpy(server_buf, lbuf + 7); +- +- port = strchr(server_buf, ':'); +- if(port != NULL) { ++ srv = token + 7; ++ port = strchr(srv, ':'); ++ if(port) { + *port = '\0'; +- port++; ++ port++; + } +- if((rv = getaddrinfo(server_buf, (port == NULL) ? +- "49" : port, &hints, &servers)) == 0) { +- for(server = servers; server != NULL && +- tac_srv_no < TAC_PLUS_MAXSERVERS; +- server = server->ai_next) { ++ ++ if((rv = getaddrinfo(srv, (port == NULL) ? "49" : port, &hints, ++ &server)) == 0) { ++ if(server) { ++ if(tac_srv[tac_srv_no].addr) ++ freeaddrinfo(tac_srv[tac_srv_no].addr); ++ if(tac_srv[tac_srv_no].key) ++ free(tac_srv[tac_srv_no].key); ++ memset(tac_srv + tac_srv_no, 0, sizeof(tacplus_server_t)); ++ + tac_srv[tac_srv_no].addr = server; +- /* use current key, if our index not yet set */ +- if(tac_key_no && !tac_srv[tac_srv_no].key) +- tac_srv[tac_srv_no].key = +- strdup(tac_srv[tac_key_no-1].key); +- tac_srv_no++; ++ } ++ else { ++ syslog(LOG_ERR, "%s: server NULL", nssname); + } + } + else { +- syslog(LOG_ERR, +- "%s: skip invalid server: %s (getaddrinfo: %s)", +- nssname, server_buf, gai_strerror(rv)); ++ syslog(LOG_ERR, "%s: invalid server: %s (getaddrinfo: %s)", ++ nssname, srv, gai_strerror(rv)); ++ return -1; ++ } ++ } ++ else if(!strncmp(token, "secret=", 7)) { ++ if(tac_srv[tac_srv_no].key) ++ free(tac_srv[tac_srv_no].key); ++ tac_srv[tac_srv_no].key = strdup(token + 7); ++ } ++ else if(!strncmp(token, "timeout=", 8)) { ++ tac_srv[tac_srv_no].timeout = (int)strtoul(token + 8, NULL, 0); ++ if(tac_srv[tac_srv_no].timeout < 0) ++ tac_srv[tac_srv_no].timeout = 0; ++ /* Limit timeout to make sure upper application not wait ++ * for a long time*/ ++ if(tac_srv[tac_srv_no].timeout > 5) ++ tac_srv[tac_srv_no].timeout = 5; ++ } ++ } ++ token = strsep(&srv_buf, delim); ++ } ++ ++ return 0; ++} ++ ++static int parse_user_priv(char *buf) ++{ ++ char *token; ++ char delim[] = ";\n\r"; ++ int priv = 0; ++ int gid = 0; ++ char *info = NULL; ++ char *group = NULL; ++ char *shell = NULL; ++ ++ token = strsep(&buf, delim); ++ while(token) { ++ if('\0' != token) { ++ if(!strncmp(token, "user_priv=", 10)) { ++ priv = (int)strtoul(token + 10, NULL, 0); ++ if(priv > MAX_TACACS_USER_PRIV || priv < MIN_TACACS_USER_PRIV) ++ { ++ priv = 0; ++ syslog(LOG_WARNING, "%s: user_priv %d out of range", ++ nssname, priv); + } + } +- else { +- syslog(LOG_WARNING, "%s: maximum number of servers (%d) " +- "exceeded, skipping", nssname, TAC_PLUS_MAXSERVERS); ++ else if(!strncmp(token, "pw_info=", 8)) { ++ if(!info) ++ info = strdup(token + 8); ++ } ++ else if(!strncmp(token, "gid=", 4)) { ++ gid = (int)strtoul(token + 4, NULL, 0); ++ } ++ else if(!strncmp(token, "group=", 6)) { ++ if(!group) ++ group = strdup(token + 6); ++ } ++ else if(!strncmp(token, "shell=", 6)) { ++ if(!shell) ++ shell = strdup(token + 6); + } + } +- else if(debug) /* ignore unrecognized lines, unless debug on */ +- syslog(LOG_WARNING, "%s: unrecognized parameter: %s", +- nssname, lbuf); ++ token = strsep(&buf, delim); + } +- fclose(conf); + ++ if(priv && gid && info && group && shell) { ++ useradd_info_t *user = &useradd_grp_list[priv]; ++ if(user->info) ++ free(user->info); ++ if(user->secondary_grp) ++ free(user->secondary_grp); ++ if(user->shell) ++ free(user->shell); ++ ++ user->gid = gid; ++ user->info = info; ++ user->secondary_grp = group; ++ user->shell = shell; ++ syslog(LOG_DEBUG, "%s: user_priv=%d info=%s gid=%d group=%s shell=%s", ++ nssname, priv, info, gid, group, shell); ++ } ++ else { ++ if(info) ++ free(info); ++ if(group) ++ free(group); ++ if(shell) ++ free(shell); ++ } + + return 0; + } + +-/* +- * Separate function so we can print first time we try to connect, +- * rather than during config. +- * Don't print at config, because often the uid lookup is one we +- * skip due to min_uid, so no reason to clutter the log. +- */ +-static void print_servers(void) ++static void init_useradd_info() + { +- static int printed = 0; +- int n; +- +- if (printed || !debug) +- return; +- printed = 1; +- +- if(tac_srv_no == 0) +- syslog(LOG_DEBUG, "%s:%s: no TACACS %s in config (or no perm)," +- " giving up", +- nssname, __FUNCTION__, tac_srv_no ? "service" : +- (*tac_service ? "server" : "service and no server")); +- +- for(n = 0; n < tac_srv_no; n++) +- syslog(LOG_DEBUG, "%s: server[%d] { addr=%s, key='%s' }", nssname, +- n, tac_srv[n].addr ? tac_ntop(tac_srv[n].addr->ai_addr) +- : "unknown", tac_srv[n].key); ++ useradd_info_t *user; ++ ++ user = &useradd_grp_list[MIN_TACACS_USER_PRIV]; ++ user->gid = 999; ++ user->info = strdup("remote_user"); ++ user->secondary_grp = strdup("docker"); ++ user->shell = strdup("/bin/bash"); ++ ++ user = &useradd_grp_list[MAX_TACACS_USER_PRIV]; ++ user->gid = 1000; ++ user->info = strdup("remote_user_su"); ++ user->secondary_grp = strdup("sudo,docker"); ++ user->shell = strdup("/bin/bash"); ++} ++ ++static int parse_config(const char *file) ++{ ++ FILE *fp; ++ char buf[512] = {0}; ++ ++ init_useradd_info(); ++ fp = fopen(file, "r"); ++ if(!fp) { ++ syslog(LOG_ERR, "%s: %s fopen failed", nssname, file); ++ return NSS_STATUS_UNAVAIL; ++ } ++ ++ debug = false; ++ tac_srv_no = 0; ++ while(fgets(buf, sizeof buf, fp)) { ++ if('#' == *buf || isspace(*buf)) ++ continue; ++ ++ if(!strncmp(buf, "debug=on", 8)) { ++ debug = true; ++ } ++ else if(!strncmp(buf, "many_to_one=y", 13)) { ++ many_to_one = true; ++ } ++ else if(!strncmp(buf, "user_priv=", 10)) { ++ parse_user_priv(buf); ++ } ++ else if(!strncmp(buf, "server=", 7)) { ++ if(TAC_PLUS_MAXSERVERS <= tac_srv_no) { ++ syslog(LOG_ERR, "%s: tac server num is more than %d", ++ nssname, TAC_PLUS_MAXSERVERS); ++ } ++ else if(0 == parse_tac_server(buf)) ++ ++tac_srv_no; ++ } ++ } ++ fclose(fp); ++ ++ if(debug) { ++ int n; ++ useradd_info_t *user; ++ ++ for(n = 0; n < tac_srv_no; n++) { ++ syslog(LOG_DEBUG, "%s: server[%d] { addr=%s, key=%s, timeout=%d }", ++ nssname, n, tac_ntop(tac_srv[n].addr->ai_addr), ++ tac_srv[n].key, tac_srv[n].timeout); ++ } ++ syslog(LOG_DEBUG, "%s: many_to_one %s", nssname, 1 == many_to_one ++ ? "enable" : "disable"); ++ for(n = MIN_TACACS_USER_PRIV; n <= MAX_TACACS_USER_PRIV; n++) { ++ user = &useradd_grp_list[n]; ++ if(user) { ++ syslog(LOG_DEBUG, "%s: user_priv[%d] { gid=%d, info=%s, group=%s, shell=%s }", ++ nssname, n, user->gid, NULL == user->info ? "NULL" : user->info, ++ NULL == user->secondary_grp ? "NULL" : user->secondary_grp, ++ NULL == user->shell ? "NULL" : user->shell); ++ } ++ } ++ } ++ ++ return 0; + } + + /* +@@ -324,15 +304,13 @@ static void print_servers(void) + */ + static int + pwcopy(char *buf, size_t len, struct passwd *srcpw, struct passwd *destpw, +- const char *usename, uint16_t tachome) ++ const char *usename) + { +- int needlen, cnt, origlen = len; +- char *shell; ++ size_t needlen; ++ int cnt; + +- if(!usename) { ++ if(!usename) + usename = srcpw->pw_name; +- tachome = 0; /* early lookups; no tachome */ +- } + + needlen = usename ? strlen(usename) + 1 : 1 + + srcpw->pw_dir ? strlen(srcpw->pw_dir) + 1 : 1 + +@@ -341,8 +319,8 @@ pwcopy(char *buf, size_t len, struct passwd *srcpw, struct passwd *destpw, + srcpw->pw_passwd ? strlen(srcpw->pw_passwd) + 1 : 1; + if(needlen > len) { + if(debug) +- syslog(LOG_DEBUG, "%s provided password buffer too small (%ld<%d)", +- nssname, (long)len, needlen); ++ syslog(LOG_DEBUG, "%s provided password buffer too small (%ld<%ld)", ++ nssname, (long)len, (long)needlen); + return 1; + } + +@@ -354,21 +332,14 @@ pwcopy(char *buf, size_t len, struct passwd *srcpw, struct passwd *destpw, + cnt++; /* allow for null byte also */ + buf += cnt; + len -= cnt; +- cnt = snprintf(buf, len, "%s", srcpw->pw_passwd ? srcpw->pw_passwd : ""); ++ /* If many-to-one mapping, set pw_passwd "a" for pam_account success */ ++ cnt = snprintf(buf, len, "%s", 0 == many_to_one ? "x" : "a"); + destpw->pw_passwd = buf; + cnt++; + buf += cnt; + len -= cnt; + cnt = snprintf(buf, len, "%s", srcpw->pw_shell ? srcpw->pw_shell : ""); + destpw->pw_shell = buf; +- shell = strrchr(buf, '/'); +- shell = shell ? shell+1 : buf; +- if (tachome && *shell == 'r') { +- tachome = 0; +- if(debug > 1) +- syslog(LOG_DEBUG, "%s tacacs login %s with user_homedir not allowed; " +- "shell is %s", nssname, srcpw->pw_name, buf); +- } + cnt++; + buf += cnt; + len -= cnt; +@@ -377,148 +348,227 @@ pwcopy(char *buf, size_t len, struct passwd *srcpw, struct passwd *destpw, + cnt++; + buf += cnt; + len -= cnt; +- if (tachome && usename) { +- char *slash, dbuf[strlen(srcpw->pw_dir) + strlen(usename)]; +- snprintf(dbuf, sizeof dbuf, "%s", srcpw->pw_dir ? srcpw->pw_dir : ""); +- slash = strrchr(dbuf, '/'); +- if (slash) { +- slash++; +- snprintf(slash, sizeof dbuf - (slash-dbuf), "%s", usename); +- } +- cnt = snprintf(buf, len, "%s", dbuf); +- } +- else +- cnt = snprintf(buf, len, "%s", srcpw->pw_dir ? srcpw->pw_dir : ""); ++ cnt = snprintf(buf, len, "%s", srcpw->pw_dir ? srcpw->pw_dir : ""); + destpw->pw_dir = buf; + cnt++; + buf += cnt; + len -= cnt; +- if(len < 0) { +- if(debug) +- syslog(LOG_DEBUG, "%s provided password buffer too small (%ld<%d)", +- nssname, (long)origlen, origlen-(int)len); +- return 1; +- } + + return 0; + } + + /* +- * Find the username or the matching tacacs privilege user in /etc/passwd +- * We use fgetpwent() so we can check the local file, always. +- * This could cause problems if somebody is using local users, ldap, and tacacs, +- * but we just require that the mapped user always be a local user. Since the +- * local user password isn't supposed to be used, that should be OK. +- * +- * We shouldn't normally find the username, because tacacs lookup should be +- * configured to follow local in nsswitch.conf, but somebody may configure the +- * other way, so we look for both the given user, and our "matching" user name +- * based on the tacacs authorization level. +- * +- * If not found, then try to map to a localuser tacacsN where N <= to the +- * TACACS+ privilege level, using the APIs in libtacplus_map.so +- * algorithm in update_mapuser() +- * Returns 0 on success, else 1 ++ * If useradd finished, user name should be deleted in conf. + */ +-static int +-find_pw_userpriv(unsigned priv, struct pwbuf *pb) ++static int delete_conf_line(const char *name) + { +- FILE *pwfile; +- struct passwd upw, tpw, *ent; +- int matches, ret, retu, rett; +- unsigned origpriv = priv; +- char ubuf[pb->buflen], tbuf[pb->buflen]; +- char tacuser[9]; /* "tacacs" followed by 1-2 digits */ +- +- tacuser[0] = '\0'; +- +- pwfile = fopen("/etc/passwd", "r"); +- if(!pwfile) { +- syslog(LOG_WARNING, "%s: failed to open /etc/passwd: %m", nssname); +- return 1; ++ FILE *fp, *fp_tmp; ++ char line[128]; ++ char del_line[128]; ++ int len = strlen(name); ++ ++ if(len >= 126) { ++ syslog(LOG_ERR, "%s: user name %s out of range 128", nssname, name); ++ return -1; ++ } ++ else { ++ snprintf(del_line, 128, "%s\n", name); + } + +-recheck: +- snprintf(tacuser, sizeof tacuser, "tacacs%u", priv); +- tpw.pw_name = upw.pw_name = NULL; +- retu = 0, rett = 0; +- for(matches=0; matches < 2 && (ent = fgetpwent(pwfile)); ) { +- if(!ent->pw_name) +- continue; /* shouldn't happen */ +- if(!strcmp(ent->pw_name, pb->name)) { +- retu = pwcopy(ubuf, sizeof(ubuf), ent, &upw, NULL, use_tachome); +- matches++; +- } +- else if(!strcmp(ent->pw_name, tacuser)) { +- rett = pwcopy(tbuf, sizeof(tbuf), ent, &tpw, NULL, use_tachome); +- matches++; ++ fp = fopen(user_conf, "r"); ++ if(!fp) { ++ syslog(LOG_ERR, "%s: %s fopen failed", nssname, user_conf); ++ return NSS_STATUS_UNAVAIL; ++ } ++ fp_tmp = fopen(user_conf_tmp, "w"); ++ if(!fp_tmp) { ++ syslog(LOG_ERR, "%s: %s fopen failed", nssname, user_conf_tmp); ++ fclose(fp); ++ return NSS_STATUS_UNAVAIL; ++ } ++ ++ while(fgets(line, sizeof line, fp)) { ++ if(strcmp(line, del_line)) { ++ fprintf(fp_tmp, "%s", line); + } + } +- if(!matches && priv > 0) { +- priv--; +- rewind(pwfile); +- goto recheck; +- } +- ret = 1; +- fclose(pwfile); +- if(matches) { +- if(priv != origpriv && debug) +- syslog(LOG_DEBUG, "%s: local user not found at privilege=%u," +- " using %s", nssname, origpriv, tacuser); +- if(upw.pw_name && !retu) +- ret = pwcopy(pb->buf, pb->buflen, &upw, pb->pw, pb->name, +- use_tachome); +- else if(tpw.pw_name && !rett) +- ret = pwcopy(pb->buf, pb->buflen, &tpw, pb->pw, pb->name, +- use_tachome); +- } +- if(ret) +- *pb->errnop = ERANGE; ++ fclose(fp_tmp); ++ fclose(fp); + +- return ret; ++ if(0 != remove(user_conf) || 0 != rename(user_conf_tmp, user_conf)) { ++ syslog(LOG_ERR, "%s: %s rewrite failed", nssname, user_conf); ++ return -1; ++ } ++ ++ return 0; + } + + /* +- * This is similar to find_pw_userpriv(), but passes in a fixed +- * name for UID lookups, where we have the mapped name from the +- * map file, so trying multiple tacacsN users would be wrong. +- * Some commonality, but ugly to factor +- * Only applies to mapped users +- * returns 0 on success ++ * If not found in local, look up in tacacs user conf. If user name is not in ++ * conf, it will be written in conf and created by command 'useradd'. When ++ * useradd command use getpwnam(), it will return when username found in conf. + */ +-static int +-find_pw_user(const char *logname, const char *tacuser, struct pwbuf *pb, +- uint16_t usetachome) ++static int create_local_user(const char *name, int level) + { +- FILE *pwfile; +- struct passwd *ent; +- int ret = 1; ++ FILE *fp; ++ useradd_info_t *user; ++ char buf[512]; ++ int len = 512; ++ int lvl, cnt; ++ bool found = false; ++ ++ fp = fopen(user_conf, "ab+"); ++ if(!fp) { ++ syslog(LOG_ERR, "%s: %s fopen failed", nssname, user_conf); ++ return -1; ++ } + +- if(!tacuser) { ++ while(fgets(buf, sizeof buf, fp)) { ++ if('#' == *buf || isspace(*buf)) ++ continue; ++ // Delete line break ++ cnt = strlen(buf); ++ buf[cnt - 1] = '\0'; ++ if(!strcmp(buf, name)) { ++ found = true; ++ break; ++ } ++ } ++ ++ /* ++ * If user is found in user_conf, it means that getpwnam is called by ++ * useradd in this NSS module. ++ */ ++ if(found) { + if(debug) +- syslog(LOG_DEBUG, "%s: passed null username, failing", nssname); ++ syslog(LOG_DEBUG, "%s: %s found in %s", nssname, name, user_conf); ++ fclose(fp); + return 1; + } + +- pwfile = fopen("/etc/passwd", "r"); +- if(!pwfile) { +- syslog(LOG_WARNING, "%s: failed to open /etc/passwd: %m", +- nssname); +- return 1; ++ snprintf(buf, len, "%s\n", name); ++ if(EOF == fputs(buf, fp)) { ++ syslog(LOG_ERR, "%s: %s write local user failed", nssname, name); ++ fclose(fp); ++ return -1; ++ } ++ fclose(fp); ++ ++ lvl = level; ++ while(lvl >= MIN_TACACS_USER_PRIV) { ++ user = &useradd_grp_list[lvl]; ++ if(user->info && user->secondary_grp && user->shell) { ++ snprintf(buf, len, "useradd -G %s \"%s\" -g %d -c \"%s\" -d /home/%s -m -s %s", ++ user->secondary_grp, name, user->gid, user->info, name, user->shell); ++ fp = popen(buf, "r"); ++ if(!fp || -1 == pclose(fp)) { ++ syslog(LOG_ERR, "%s: useradd popen failed errno=%d %s", ++ nssname, errno, strerror(errno)); ++ delete_conf_line(name); ++ return -1; ++ } ++ if(debug) ++ syslog(LOG_DEBUG, "%s: create local user %s success", nssname, name); ++ delete_conf_line(name); ++ return 0; ++ } ++ lvl--; ++ } ++ ++ return -1; ++} ++ ++/* ++ * Lookup user in /etc/passwd, and fill up passwd info if found. ++ */ ++static int lookup_pw_local(char* username, struct pwbuf *pb, bool *found) ++{ ++ FILE *fp; ++ struct passwd *pw = NULL; ++ int ret = 0; ++ ++ if(!username) { ++ syslog(LOG_ERR, "%s: username invalid in check passwd", nssname); ++ return -1; + } + +- pb->pw->pw_name = NULL; /* be paranoid */ +- for(ret = 1; ret && (ent = fgetpwent(pwfile)); ) { +- if(!ent->pw_name) +- continue; /* shouldn't happen */ +- if(!strcmp(ent->pw_name, tacuser)) { +- ret = pwcopy(pb->buf, pb->buflen, ent, pb->pw, logname, usetachome); ++ fp = fopen("/etc/passwd", "r"); ++ if(!fp) { ++ syslog(LOG_ERR, "%s: /etc/passwd fopen failed", nssname); ++ return -1; ++ } ++ ++ while(0 != (pw = fgetpwent(fp))) { ++ if(!strcmp(pw->pw_name, username)) { ++ *found = true; ++ ret = pwcopy(pb->buf, pb->buflen, pw, pb->pw, username); ++ if(ret) ++ *pb->errnop = ERANGE; + break; + } + } +- fclose(pwfile); +- if(ret) +- *pb->errnop = ERANGE; ++ fclose(fp); ++ return ret; ++} ++ ++/* ++ * Lookup local user passwd info for TACACS+ user. If not found, local user will ++ * be created by user mapping strategy. ++ */ ++static int lookup_user_pw(struct pwbuf *pb, int level) ++{ ++ char *username = NULL; ++ char buf[128]; ++ int len = 128; ++ bool found = false; ++ int ret = 0; ++ ++ if(level < MIN_TACACS_USER_PRIV || level > MAX_TACACS_USER_PRIV) { ++ syslog(LOG_ERR, "%s: TACACS+ user %s privilege %d invalid", nssname, pb->name, level); ++ return -1; ++ } ++ ++ /* ++ * If many-to-one user mapping disable, create local user for each TACACS+ user ++ * The username of local user and TACACS+ user is the same. If many-to-one enable, ++ * look up the mapped local user name and passwd info. ++ */ ++ if(0 == many_to_one) { ++ username = pb->name; ++ } ++ else { ++ int lvl = level; ++ useradd_info_t *user; ++ ++ while(lvl >= MIN_TACACS_USER_PRIV) { ++ user = &useradd_grp_list[lvl]; ++ if(user->info && user->secondary_grp && user->shell) { ++ snprintf(buf, len, "%s", user->info); ++ username = buf; ++ if(debug) ++ syslog(LOG_DEBUG, "%s: %s mapping local user %s", nssname, ++ pb->name, username); ++ break; ++ } ++ lvl--; ++ } ++ } ++ ++ ret = lookup_pw_local(username, pb, &found); ++ if(debug) ++ syslog(LOG_DEBUG, "%s: %s passwd %s found in local", nssname, username, ++ found ? "is" : "isn't"); ++ if(0 != ret || found) ++ return ret; ++ ++ if(0 != create_local_user(username, level)) ++ return -1; ++ ++ ret = lookup_pw_local(username, pb, &found); ++ if(0 == ret && !found) { ++ syslog(LOG_ERR, "%s: %s not found in local after useradd", nssname, pb->name); ++ ret = -1; ++ } + + return ret; + } +@@ -532,6 +582,7 @@ static int + got_tacacs_user(struct tac_attrib *attr, struct pwbuf *pb) + { + unsigned long priv_level = 0; ++ int ret; + + while(attr != NULL) { + /* we are looking for the privilege attribute, can be in several forms, +@@ -550,14 +601,20 @@ got_tacacs_user(struct tac_attrib *attr, struct pwbuf *pb) + /* if this fails, we leave priv_level at 0, which is + * least privileged, so that's OK, but at least report it + */ +- if(ok == val && debug) +- syslog(LOG_WARNING, "%s: non-numeric privilege for %s, (%s)", +- nssname, pb->name, attr->attr); ++ if(debug) ++ syslog(LOG_DEBUG, "%s: privilege for %s, (%lu)", ++ nssname, pb->name, priv_level); + } + attr = attr->next; + } + +- return find_pw_userpriv(priv_level, pb); ++ ret = lookup_user_pw(pb, priv_level); ++ if(!ret && debug) ++ syslog(LOG_DEBUG, "%s: pw_name=%s, pw_passwd=%s, pw_shell=%s, dir=%s", ++ nssname, pb->pw->pw_name, pb->pw->pw_passwd, pb->pw->pw_shell, ++ pb->pw->pw_dir); ++ ++ return ret; + } + + /* +@@ -570,9 +627,13 @@ connect_tacacs(struct tac_attrib **attr, int srvr) + { + int fd; + ++ if(!*tac_service) /* reported at config file processing */ ++ return -1; ++ + fd = tac_connect_single(tac_srv[srvr].addr, tac_srv[srvr].key, NULL, +- vrfname[0]?vrfname:NULL); ++ tac_srv[srvr].timeout); + if(fd >= 0) { ++ *attr = NULL; /* so tac_add_attr() allocates memory */ + tac_add_attrib(attr, "service", tac_service); + if(tac_protocol[0]) + tac_add_attrib(attr, "protocol", tac_protocol); +@@ -598,34 +659,9 @@ lookup_tacacs_user(struct pwbuf *pb) + { + struct areply arep; + int ret = 1, done = 0; +- struct tac_attrib *attr = NULL; ++ struct tac_attrib *attr; + int tac_fd, srvr; + +- if (exclude_users) { +- char *user, *list; +- list = strdup(exclude_users); +- if (list) { +- static const char *delim = ", \t\n"; +- bool islocal = 0; +- user = strtok(list, delim); +- list = NULL; +- while (user) { +- if(!strcmp(user, pb->name)) { +- islocal = 1; +- break; +- } +- user = strtok(NULL, delim); +- } +- free(list); +- if (islocal) +- return 2; +- } +- } +- +- if(!*tac_service) /* reported at config file processing */ +- return ret; +- print_servers(); +- + for(srvr=0; srvr < tac_srv_no && !done; srvr++) { + arep.msg = NULL; + arep.attr = NULL; +@@ -636,14 +672,13 @@ lookup_tacacs_user(struct pwbuf *pb) + syslog(LOG_WARNING, "%s: failed to connect TACACS+ server %s," + " ret=%d: %m", nssname, tac_srv[srvr].addr ? + tac_ntop(tac_srv[srvr].addr->ai_addr) : "unknown", tac_fd); +- tac_free_attrib(&attr); + continue; + } +- ret = tac_author_send(tac_fd, pb->name, "", tac_rhost, attr); ++ ret = tac_author_send(tac_fd, pb->name, "", "", attr); + if(ret < 0) { + if(debug) +- syslog(LOG_WARNING, "%s: TACACS+ server %s authorization failed (%d) " +- " user (%s)", nssname, tac_srv[srvr].addr ? ++ syslog(LOG_WARNING, "%s: TACACS+ server %s send failed (%d) for" ++ " user %s: %m", nssname, tac_srv[srvr].addr ? + tac_ntop(tac_srv[srvr].addr->ai_addr) : "unknown", ret, + pb->name); + } +@@ -668,14 +703,11 @@ lookup_tacacs_user(struct pwbuf *pb) + if(arep.status == AUTHOR_STATUS_PASS_ADD || + arep.status == AUTHOR_STATUS_PASS_REPL) { + ret = got_tacacs_user(arep.attr, pb); +- if(debug>1) ++ if(debug) + syslog(LOG_DEBUG, "%s: TACACS+ server %s successful for user %s." + " local lookup %s", nssname, + tac_ntop(tac_srv[srvr].addr->ai_addr), pb->name, +- ret?"OK":"no match"); +- else if(debug) +- syslog(LOG_DEBUG, "%s: TACACS+ server %s successful for user %s", +- nssname, tac_ntop(tac_srv[srvr].addr->ai_addr), pb->name); ++ ret == 0?"OK":"no match"); + done = 1; /* break out of loop after arep cleanup */ + } + else { +@@ -692,30 +724,12 @@ lookup_tacacs_user(struct pwbuf *pb) + tac_free_attrib(&arep.attr); + } + +- return ret < 0? 1 : ret; +-} +- +-static int +-lookup_mapped_uid(struct pwbuf *pb, uid_t uid, uid_t auid, int session) +-{ +- char *loginname, mappedname[256]; +- uint16_t flag; +- +- mappedname[0] = '\0'; +- loginname = lookup_mapuid(uid, auid, session, +- mappedname, sizeof mappedname, &flag); +- if(loginname) +- return find_pw_user(loginname, mappedname, pb, flag & MAP_USERHOMEDIR); +- return 1; ++ return ret; + } + + /* + * This is an NSS entry point. +- * We implement getpwnam(), because we remap from the tacacs login +- * to the local tacacs0 ... tacacs15 users for all other info, and so +- * the normal order of "passwd tacplus" (possibly with ldap or anything +- * else prior to tacplus) will mean we only get used when there isn't +- * a local user to be found. ++ * We implement getpwnam(), because we remap from the tacacs. + * + * We try the lookup to the tacacs server first. If we can't make a + * connection to the server for some reason, we also try looking up +@@ -730,20 +744,25 @@ enum nss_status _nss_tacplus_getpwnam_r(const char *name, struct passwd *pw, + int result; + struct pwbuf pbuf; + +- result = nss_tacplus_config(errnop, config_file, 1); +- conf_parsed = result == 0 ? 2 : 1; ++ /* ++ * When filename completion is used with the tab key in bash, getpwnam ++ * is invoked. And the parameter "name" is '*'. In order not to connect to ++ * TACACS+ server frequently, check user name whether is valid. ++ */ ++ if(!strcmp(name, "*")) ++ return NSS_STATUS_NOTFOUND; + +- get_remote_addr(); ++ result = parse_config(config_file); + +- if(result) { /* no config file, no servers, etc. */ +- /* this is a debug because privileges may not allow access */ +- if(debug) +- syslog(LOG_DEBUG, "%s: bad config or server line for nss_tacplus", ++ if(result) { ++ syslog(LOG_ERR, "%s: bad config or server line for nss_tacplus", ++ nssname); ++ } ++ else if(0 == tac_srv_no) { ++ syslog(LOG_WARNING, "%s: no tacacs server in config for nss_tacplus", + nssname); + } + else { +- int lookup; +- + /* marshal the args for the lower level functions */ + pbuf.name = (char *)name; + pbuf.pw = pw; +@@ -751,126 +770,13 @@ enum nss_status _nss_tacplus_getpwnam_r(const char *name, struct passwd *pw, + pbuf.buflen = buflen; + pbuf.errnop = errnop; + +- lookup = lookup_tacacs_user(&pbuf); +- if(!lookup) ++ if(0 == lookup_tacacs_user(&pbuf)) { + status = NSS_STATUS_SUCCESS; +- else if(lookup == 1) { /* 2 means exclude_users match */ +- uint16_t flag; +- /* +- * If we can't contact a tacacs server (either not configured, or +- * more likely, we aren't running as root and the config for the +- * server is not readable by our uid for security reasons), see if +- * we can find the user via the mapping database, and if so, use +- * that. This will work for non-root users as long as the requested +- * name is in use (that is, logged in), which will be the most +- * common case of wanting to use the original login name by non-root +- * users. +- */ +- char *mapname = lookup_mapname(name, -1, -1, NULL, &flag); +- if(mapname != name && !find_pw_user(name, mapname, &pbuf, +- flag & MAP_USERHOMEDIR)) +- status = NSS_STATUS_SUCCESS; ++ if(debug) ++ syslog(LOG_DEBUG, "%s: name=%s, pw_name=%s, pw_passwd=%s, pw_shell=%s", ++ nssname, name, pw->pw_name, pw->pw_passwd, pw->pw_shell); + } + } +- return status; +-} + +-/* +- * This is an NSS entry point. +- * We implement getpwuid(), for anything that wants to get the original +- * login name from the uid. +- * If it matches an entry in the map, we use that data to replace +- * the data from the local passwd file (not via NSS). +- * locally from the map. +- * +- * This can be made to work 2 different ways, and we need to choose +- * one, or make it configurable. +- * +- * 1) Given a valid auid and a session id, and a mapped user logged in, +- * we'll match only that user. That is, we can only do the lookup +- * successfully for child processes of the mapped tacacs login, and +- * only while still logged in (map entry is valid). +- * +- * 2) Use auid/session wildcards, and and always match on the first valid +- * tacacs map file entry. This means if two tacacs users are logged in +- * at the same privilege level at the same time, uid lookups for ps, ls, +- * etc. will return the first (in the map file, not necessarily first +- * logged in) mapped name. +- * +- * For now, if auid and session are set, I try them, and if that lookup +- * fails, try the wildcard. +- * +- * Only works while the UID is in use for a mapped user, and only +- * for processes invoked from that session. Other callers will +- * just get the files, ldap, or nis entry for the UID +- * Only works while the UID is in use for a mapped user, and returns +- * the first match from the mapped users. +- */ +-enum nss_status _nss_tacplus_getpwuid_r(uid_t uid, struct passwd *pw, +- char *buffer, size_t buflen, int *errnop) +-{ +- struct pwbuf pb; +- enum nss_status status = NSS_STATUS_NOTFOUND; +- int session, ret; +- uid_t auid; +- +- ret = nss_tacplus_config(errnop, config_file, 1); +- conf_parsed = ret == 0 ? 2 : 1; +- +- if (min_uid != ~0U && uid < min_uid) { +- if(debug > 1) +- syslog(LOG_DEBUG, "%s: uid %u < min_uid %u, don't lookup", +- nssname, uid, min_uid); +- return status; +- } +- +- auid = audit_getloginuid(); /* audit_setloginuid not called */ +- session = map_get_sessionid(); +- +- /* marshal the args for the lower level functions */ +- pb.pw = pw; +- pb.buf = buffer; +- pb.buflen = buflen; +- pb.errnop = errnop; +- pb.name = NULL; +- +- /* +- * the else case will only be called if we don't have an auid or valid +- * sessionid, since otherwise the first call will be using wildcards, +- * since the getloginuid and get_sessionid calls will "fail". +- */ +- if(!lookup_mapped_uid(&pb, uid, auid, session)) +- status = NSS_STATUS_SUCCESS; +- else if((auid != (uid_t)-1 || session != ~0U) && +- !lookup_mapped_uid(&pb, uid, (uid_t)-1, ~0)) +- status = NSS_STATUS_SUCCESS; + return status; + } +- +-static void get_remote_addr(void) +-{ +- struct sockaddr_storage addr; +- socklen_t len = sizeof addr; +- char ipstr[INET6_ADDRSTRLEN]; +- +- /* This is so we can fill in the rhost field when we talk to the +- * TACACS+ server, when it's an ssh connection, so sites that refuse +- * authorization unless from specific IP addresses will get that +- * information. It's pretty much of a hack, but it works. +- */ +- if (getpeername(0, (struct sockaddr*)&addr, &len) == -1) +- return; +- +- *ipstr = 0; +- if (addr.ss_family == AF_INET) { +- struct sockaddr_in *s = (struct sockaddr_in *)&addr; +- inet_ntop(AF_INET, &s->sin_addr, ipstr, sizeof ipstr); +- } else { +- struct sockaddr_in6 *s = (struct sockaddr_in6 *)&addr; +- inet_ntop(AF_INET6, &s->sin6_addr, ipstr, sizeof ipstr); +- } +- +- snprintf(tac_rhost, sizeof tac_rhost, "%s", ipstr); +- if(debug > 1 && tac_rhost[0]) +- syslog(LOG_DEBUG, "%s: rhost=%s", nssname, tac_rhost); +-} +diff --git a/tacplus_nss.conf b/tacplus_nss.conf +index bb4eb1e..7cb756f 100644 +--- a/tacplus_nss.conf ++++ b/tacplus_nss.conf +@@ -1,53 +1,50 @@ +-#%NSS_TACPLUS-1.0 +-# Install this file as /etc/tacplus_nss.conf +-# Edit /etc/nsswitch.conf to add tacplus to the passwd lookup, similar to this +-# where tacplus precede compat (or files), and depending on local policy can +-# follow or precede ldap, nis, etc. +-# passwd: tacplus compat +-# +-# Servers are tried in the order listed, and once a server +-# replies, no other servers are attempted in a given process instantiation +-# +-# This configuration is similar to the libpam_tacplus configuration, but +-# is maintained as a configuration file, since nsswitch.conf doesn't +-# support passing parameters. Parameters must start in the first +-# column, and parsing stops at the first whitespace +- +-# if set, errors and other issues are logged with syslog +-# debug=1 ++# Configuration for libnss-tacplus + +-# min_uid is the minimum uid to lookup via tacacs. Setting this to 0 +-# means uid 0 (root) is never looked up, good for robustness and performance +-# Cumulus Linux ships with it set to 1001, so we never lookup our standard +-# local users, including the cumulus uid of 1000. Should not be greater +-# than the local tacacs{0..15} uids +-min_uid=1001 ++# debug - If you want to open debug log, set it on ++# ++# Default: off ++# debug=on + +-# This is a comma separated list of usernames that are never sent to +-# a tacacs server, they cause an early not found return. ++# src_ip - set source address of TACACS+ protocl packets + # +-# "*" is not a wild card. While it's not a legal username, it turns out +-# that during pathname completion, bash can do an NSS lookup on "*" +-# To avoid server round trip delays, or worse, unreachable server delays +-# on filename completion, we include "*" in the exclusion list. +-exclude_users=root,cumulus,quagga,sshd,ntp,* ++# Default: None (it means the ip address of out port) ++# src_ip=2.2.2.2 + +-# The include keyword allows centralizing the tacacs+ server information +-# including the IP address and shared secret +-include=/etc/tacplus_servers ++# server - set ip address, tcp port, secret string and timeout for TACACS+ servers ++# The maximum number of servers is 8. If there is no TACACS+ server, libnss-tacplus ++# will always return pwname not found. ++# ++# Default: None (no TACACS+ server) ++# server=1.1.1.1:49,secret=test,timeout=3 + +-# The server IP address can be optionally followed by a ':' and a port +-# number (server=1.1.1.1:49). It is strongly recommended that you NOT +-# add secret keys to this file, because it is world readable. +-#secret=SECRET1 +-#server=1.1.1.1 ++# user_priv - set the map between TACACS+ user privilege and local user's passwd ++# If TACACS+ user validate ok, it will get passwd info from local user which is ++# specially created for TACACS+ user in libnss-tacplus. This configuration is provided ++# to create local user. There is two user privilege map by default. ++# If the TACACS+ user's privilege value is in [1, 14], the config of user_priv 1 is ++# used to create local user. If user_priv 7 is added, the TACACS+ user which privilege ++# value is in [1, 6] will get the config of user_priv 1, and the value in [7, 14] will ++# get user_priv 7. ++# ++# If the passwd info of mapped local user is modified, like gid and shell, the new TACACS+ ++# user will create local user by the new config. But the old TACACS+ user which has logged ++# will not modify its mapped local user's passwd info. So it's better to keep this ++# configuration unchanged, not to modified at the running time. Or simply delete the old ++# mapped local user after modified. ++# ++# NOTE: If many_to_one enables, 'pw_info' is used for mapped local user name. So note the ++# naming rule for Linux user name when you set 'pw_info', and keep it different from other ++# 'pw_info'. ++# ++# Default: ++# user_priv=15;pw_info=remote_user_su;gid=1000;group=sudo,docker;shell=/bin/bash ++# user_priv=1;pw_info=remote_user;gid=999;group=docker;shell=/bin/bash + +-# The connection timeout for an NSS library should be short, since it is +-# invoked for many programs and daemons, and a failure is usually not +-# catastrophic. Not set or set to a negative value disables use of poll(). +-# This follows the include of tacplus_servers, so it can override any +-# timeout value set in that file. +-# It's important to have this set in this file, even if the same value +-# as in tacplus_servers, since tacplus_servers should not be readable +-# by users other than root. +-timeout=5 ++# many_to_one - create one local user for many TACACS+ users which has the same privilege ++# The parameter 'pw_info' in 'user_priv' is used for the mapped local user name. ++# The default config is one to one mapping. It will create local user for each TACACS+ user ++# which has different username. The user mapping strategy should be set before enables ++# TACACS+, and keep constant at the running time. ++# ++# Default: many_to_one=n ++# many_to_one=y +-- +2.7.4 + diff --git a/src/tacacs/nss/Makefile b/src/tacacs/nss/Makefile new file mode 100644 index 000000000000..4f1a337b34b4 --- /dev/null +++ b/src/tacacs/nss/Makefile @@ -0,0 +1,22 @@ +.ONESHELL: +SHELL = /bin/bash +.SHELLFLAGS += -e + +MAIN_TARGET = libnss-tacplus_$(NSS_TACPLUS_VERSION)_amd64.deb + +$(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : + # Obtain libnss-tacplus + rm -rf ./libnss-tacplus + git clone https://github.com/daveolson53/libnss-tacplus.git + pushd ./libnss-tacplus + git checkout -f 19008ab + + # Apply patch + git apply ../0001-Modify-user-map-profile.patch + + dpkg-buildpackage -rfakeroot -b -us -uc + popd + + mv $(DERIVED_TARGETS) $* $(DEST)/ + +$(addprefix $(DEST)/, $(DERIVED_TARGETS)): $(DEST)/% : $(DEST)/$(MAIN_TARGET) diff --git a/src/tacacs/pam/0001-Don-t-init-declarations-in-a-for-loop.patch b/src/tacacs/pam/0001-Don-t-init-declarations-in-a-for-loop.patch new file mode 100644 index 000000000000..f9a9c29eb93f --- /dev/null +++ b/src/tacacs/pam/0001-Don-t-init-declarations-in-a-for-loop.patch @@ -0,0 +1,45 @@ +From f293353127c504490f8d892afe39766ec94137bf Mon Sep 17 00:00:00 2001 +From: Liuqu +Date: Sun, 8 Oct 2017 07:32:11 -0700 +Subject: [PATCH 1/2] Don't init declarations in a for loop + +* It comes from the commit "3299028... Don't init declarations in + a for loop", and modified source format to resolve conflict in + v1.4.1 +--- + libtac/lib/author_r.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/libtac/lib/author_r.c b/libtac/lib/author_r.c +index a028144..f3b544e 100644 +--- a/libtac/lib/author_r.c ++++ b/libtac/lib/author_r.c +@@ -47,6 +47,7 @@ int tac_author_read(int fd, struct areply *re) { + char *msg = NULL; + int timeleft; + re->msg = NULL; ++ unsigned int r = 0; + + bzero(re, sizeof(struct areply)); + if (tac_readtimeout_enable && +@@ -132,7 +133,7 @@ int tac_author_read(int fd, struct areply *re) { + pktp = (u_char *) tb + TAC_AUTHOR_REPLY_FIXED_FIELDS_SIZE; + + /* cycle through the arguments supplied in the packet */ +- for (unsigned int r = 0; r < tb->arg_cnt && r < TAC_PLUS_MAX_ARGCOUNT; r++) { ++ for (r = 0; r < tb->arg_cnt && r < TAC_PLUS_MAX_ARGCOUNT; r++) { + if (len_from_body > packet_read || ((void *)pktp - (void *) tb) > packet_read) { + TACSYSLOG((LOG_ERR,\ + "%s: arguments supplied in packet seem to exceed its size",\ +@@ -205,7 +206,7 @@ int tac_author_read(int fd, struct areply *re) { + TACSYSLOG((LOG_DEBUG, "Args cnt %d", tb->arg_cnt)); + /* argp points to current argument string + pktp points to current argument length */ +- for (unsigned int r = 0; r < tb->arg_cnt && r < TAC_PLUS_MAX_ARGCOUNT; ++ for (r = 0; r < tb->arg_cnt && r < TAC_PLUS_MAX_ARGCOUNT; + r++) { + unsigned char buff[256]; + unsigned char *sep; +-- +2.7.4 + diff --git a/src/tacacs/pam/0002-Fix-libtac2-bin-install-directory-error.patch b/src/tacacs/pam/0002-Fix-libtac2-bin-install-directory-error.patch new file mode 100644 index 000000000000..28518b3d2449 --- /dev/null +++ b/src/tacacs/pam/0002-Fix-libtac2-bin-install-directory-error.patch @@ -0,0 +1,19 @@ +From 85bae6b84d93c4b243d29ee08ff7030376bf80cb Mon Sep 17 00:00:00 2001 +From: Liuqu +Date: Sun, 8 Oct 2017 19:39:23 -0700 +Subject: [PATCH 2/2] Fix libtac2-bin install directory error + +--- + debian/libtac2-bin.install | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/debian/libtac2-bin.install b/debian/libtac2-bin.install +index 236670a..1df36c6 100644 +--- a/debian/libtac2-bin.install ++++ b/debian/libtac2-bin.install +@@ -1 +1 @@ +-usr/sbin ++usr/bin/* +-- +2.7.4 + diff --git a/src/tacacs/pam/Makefile b/src/tacacs/pam/Makefile new file mode 100644 index 000000000000..707668791402 --- /dev/null +++ b/src/tacacs/pam/Makefile @@ -0,0 +1,25 @@ +.ONESHELL: +SHELL = /bin/bash +.SHELLFLAGS += -e + +MAIN_TARGET = libpam-tacplus_$(PAM_TACPLUS_VERSION)_amd64.deb +DERIVED_TARGETS = libtac2_$(PAM_TACPLUS_VERSION)_amd64.deb \ + libtac-dev_$(PAM_TACPLUS_VERSION)_amd64.deb + +$(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : + # Obtain pam_tacplus + rm -rf ./pam_tacplus + git clone https://github.com/jeroennijhof/pam_tacplus.git + pushd ./pam_tacplus + git checkout -f v1.4.1 + + # Apply patch + git apply ../0001-Don-t-init-declarations-in-a-for-loop.patch + git apply ../0002-Fix-libtac2-bin-install-directory-error.patch + + dpkg-buildpackage -rfakeroot -b -us -uc + popd + + mv $(DERIVED_TARGETS) $* $(DEST)/ + +$(addprefix $(DEST)/, $(DERIVED_TARGETS)): $(DEST)/% : $(DEST)/$(MAIN_TARGET) From 50bd2cb2dde9b1b78203022ca3e9ded66eb1775e Mon Sep 17 00:00:00 2001 From: kram Date: Thu, 14 Dec 2017 11:59:00 -0800 Subject: [PATCH 15/58] update swss refpoint --- src/sonic-swss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-swss b/src/sonic-swss index 5aabe44417c4..34f5fdcb7198 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit 5aabe44417c4d31e39a5cfb91b36f7338cebfe81 +Subproject commit 34f5fdcb7198da33f36fba2ce5451e8fde3820e5 From 51bddfaefef3e2d68da125402d68411472e863a3 Mon Sep 17 00:00:00 2001 From: kram Date: Mon, 18 Dec 2017 15:33:56 -0800 Subject: [PATCH 16/58] update refpoint of swss --- src/sonic-swss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-swss b/src/sonic-swss index 0b921c6f03a6..2ee06fa9a25e 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit 0b921c6f03a61de9ed6e3665de6642b7a38cf8a3 +Subproject commit 2ee06fa9a25e02e0947731e4cbfc38131798bdcc From f5381e4de56844ecded837a6a816b228681c7996 Mon Sep 17 00:00:00 2001 From: kram Date: Wed, 20 Dec 2017 10:23:35 -0800 Subject: [PATCH 17/58] library dependency for stack unroll --- platform/barefoot/docker-syncd-bfn/Dockerfile.j2 | 2 +- sonic-slave/Dockerfile | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/platform/barefoot/docker-syncd-bfn/Dockerfile.j2 b/platform/barefoot/docker-syncd-bfn/Dockerfile.j2 index 54e55e110890..3e31e4b94417 100755 --- a/platform/barefoot/docker-syncd-bfn/Dockerfile.j2 +++ b/platform/barefoot/docker-syncd-bfn/Dockerfile.j2 @@ -11,7 +11,7 @@ debs/{{ deb }}{{' '}} {%- endfor -%} debs/ -RUN apt-get install -y libxml2 libpcap-dev libusb-1.0-0-dev libcurl3 libcurl4-gnutls-dev +RUN apt-get install -y libxml2 libpcap-dev libusb-1.0-0-dev libcurl3 libcurl4-gnutls-dev libunwind8-dev RUN dpkg -i \ {% for deb in docker_syncd_bfn_debs.split(' ') -%} diff --git a/sonic-slave/Dockerfile b/sonic-slave/Dockerfile index ea40a4ce4c65..a43bdd5c1550 100644 --- a/sonic-slave/Dockerfile +++ b/sonic-slave/Dockerfile @@ -117,6 +117,7 @@ RUN apt-get update && apt-get install -y \ # For BFN sdk build libusb-1.0-0-dev \ libcurl3-nss-dev \ + libunwind8-dev \ telnet \ # For build image cpio \ From c171dfc59fda8bd5e3b3fba20575b27f43543e27 Mon Sep 17 00:00:00 2001 From: kram Date: Wed, 20 Dec 2017 21:59:10 -0800 Subject: [PATCH 18/58] update refpoint to bf-master --- src/sonic-swss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-swss b/src/sonic-swss index 2ee06fa9a25e..6ad7ece48fc4 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit 2ee06fa9a25e02e0947731e4cbfc38131798bdcc +Subproject commit 6ad7ece48fc4fa3a1c46fdf5cc507eddcdaf8496 From 547049a806f5fba25477b79ee41bbca6205f2b25 Mon Sep 17 00:00:00 2001 From: kram Date: Tue, 2 Jan 2018 18:29:37 -0800 Subject: [PATCH 19/58] Allow multi platform support - infra (more changes to follow) --- .../montara/switch-sai.conf | 33 +++++++++++++++++++ .../mavericks/switch-sai.conf | 33 +++++++++++++++++++ platform/barefoot/bfn-platform.mk | 5 +++ platform/barefoot/rules.mk | 5 +-- 4 files changed, 74 insertions(+), 2 deletions(-) create mode 100644 device/barefoot/x86_64-accton_wedge100bf_32x-r0/montara/switch-sai.conf create mode 100644 device/barefoot/x86_64-accton_wedge100bf_65x-r0/mavericks/switch-sai.conf create mode 100644 platform/barefoot/bfn-platform.mk diff --git a/device/barefoot/x86_64-accton_wedge100bf_32x-r0/montara/switch-sai.conf b/device/barefoot/x86_64-accton_wedge100bf_32x-r0/montara/switch-sai.conf new file mode 100644 index 000000000000..220a080011ee --- /dev/null +++ b/device/barefoot/x86_64-accton_wedge100bf_32x-r0/montara/switch-sai.conf @@ -0,0 +1,33 @@ +{ + "chip_list": [ + { + "id": "asic-0", + "chip_family": "Tofino", + "instance": 0, + "pcie_sysfs_prefix": "/sys/devices/pci0000:00/0000:00:03.0/0000:05:00.0", + "pcie_domain": 0, + "pcie_bus": 5, + "pcie_fn": 0, + "pcie_dev": 0, + "pcie_int_mode": 1, + "sds_fw_path": "share/tofino_sds_fw/avago/firmware" + } + ], + "instance": 0, + "p4_program_list": [ + { + "id": "pgm-0", + "instance": 0, + "path": "switch", + "program-name": "switch", + "pd": "lib/tofinopd/switch/libpd.so", + "pd-thrift": "lib/tofinopd/switch/libpdthrift.so", + "table-config": "share/tofinopd/switch/context.json", + "tofino-bin": "share/tofinopd/switch/tofino.bin", + "switchapi": "lib/libswitchapi.so", + "switchsai": "lib/libswitchsai.so", + "agent0": "lib/mavericks/libpltfm_mgr.so", + "switchapi_port_add": false + } + ] +} diff --git a/device/barefoot/x86_64-accton_wedge100bf_65x-r0/mavericks/switch-sai.conf b/device/barefoot/x86_64-accton_wedge100bf_65x-r0/mavericks/switch-sai.conf new file mode 100644 index 000000000000..220a080011ee --- /dev/null +++ b/device/barefoot/x86_64-accton_wedge100bf_65x-r0/mavericks/switch-sai.conf @@ -0,0 +1,33 @@ +{ + "chip_list": [ + { + "id": "asic-0", + "chip_family": "Tofino", + "instance": 0, + "pcie_sysfs_prefix": "/sys/devices/pci0000:00/0000:00:03.0/0000:05:00.0", + "pcie_domain": 0, + "pcie_bus": 5, + "pcie_fn": 0, + "pcie_dev": 0, + "pcie_int_mode": 1, + "sds_fw_path": "share/tofino_sds_fw/avago/firmware" + } + ], + "instance": 0, + "p4_program_list": [ + { + "id": "pgm-0", + "instance": 0, + "path": "switch", + "program-name": "switch", + "pd": "lib/tofinopd/switch/libpd.so", + "pd-thrift": "lib/tofinopd/switch/libpdthrift.so", + "table-config": "share/tofinopd/switch/context.json", + "tofino-bin": "share/tofinopd/switch/tofino.bin", + "switchapi": "lib/libswitchapi.so", + "switchsai": "lib/libswitchsai.so", + "agent0": "lib/mavericks/libpltfm_mgr.so", + "switchapi_port_add": false + } + ] +} diff --git a/platform/barefoot/bfn-platform.mk b/platform/barefoot/bfn-platform.mk new file mode 100644 index 000000000000..7cc491921de4 --- /dev/null +++ b/platform/barefoot/bfn-platform.mk @@ -0,0 +1,5 @@ +BFN_PLATFORM = bfnplatform_1.0.0_amd64.deb +$(BFN_PLATFORM)_URL = "https://www.dropbox.com/s/pname82eqzwbrcd/bfnplatform_1.0.0_amd64.deb?dl=0" + +SONIC_ONLINE_DEBS += $(BFN_PLATFORM) # $(BFN_SAI_DEV) +$(BFN_SAI_DEV)_DEPENDS += $(BFN_PLATFORM) diff --git a/platform/barefoot/rules.mk b/platform/barefoot/rules.mk index 507e6b7daeea..ab9a1679af53 100644 --- a/platform/barefoot/rules.mk +++ b/platform/barefoot/rules.mk @@ -8,12 +8,13 @@ include $(PLATFORM_PATH)/one-image.mk include $(PLATFORM_PATH)/libsaithrift-dev.mk include $(PLATFORM_PATH)/python-saithrift.mk include $(PLATFORM_PATH)/docker-ptf-bfn.mk +include $(PLATFORM_PATH)/bfn-platform.mk SONIC_ALL += $(SONIC_ONE_IMAGE) \ $(DOCKER_FPM) # Inject sai into sairedis -$(LIBSAIREDIS)_DEPENDS += $(BFN_SAI) #$(LIBSAITHRIFT_DEV_BFN) +$(LIBSAIREDIS)_DEPENDS += $(BFN_SAI) $(BFN_PLATFORM)#$(LIBSAITHRIFT_DEV_BFN) # Runtime dependency on sai is set only for syncd -$(SYNCD)_RDEPENDS += $(BFN_SAI) +$(SYNCD)_RDEPENDS += $(BFN_SAI) $(BFN_PLATFORM) From 4eec93af5b172346f4d5cfe1f73ad9fbb184229b Mon Sep 17 00:00:00 2001 From: kram Date: Tue, 2 Jan 2018 22:25:59 -0800 Subject: [PATCH 20/58] update relative path to include platform for clarity --- .../x86_64-accton_wedge100bf_32x-r0/montara/switch-sai.conf | 2 +- .../x86_64-accton_wedge100bf_65x-r0/mavericks/switch-sai.conf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/device/barefoot/x86_64-accton_wedge100bf_32x-r0/montara/switch-sai.conf b/device/barefoot/x86_64-accton_wedge100bf_32x-r0/montara/switch-sai.conf index 220a080011ee..ec5684bb7f50 100644 --- a/device/barefoot/x86_64-accton_wedge100bf_32x-r0/montara/switch-sai.conf +++ b/device/barefoot/x86_64-accton_wedge100bf_32x-r0/montara/switch-sai.conf @@ -26,7 +26,7 @@ "tofino-bin": "share/tofinopd/switch/tofino.bin", "switchapi": "lib/libswitchapi.so", "switchsai": "lib/libswitchsai.so", - "agent0": "lib/mavericks/libpltfm_mgr.so", + "agent0": "lib/platform/x86_64-accton_wedge100bf_32x-r0/libpltfm_mgr.so", "switchapi_port_add": false } ] diff --git a/device/barefoot/x86_64-accton_wedge100bf_65x-r0/mavericks/switch-sai.conf b/device/barefoot/x86_64-accton_wedge100bf_65x-r0/mavericks/switch-sai.conf index 220a080011ee..c1ebfc3fd4e4 100644 --- a/device/barefoot/x86_64-accton_wedge100bf_65x-r0/mavericks/switch-sai.conf +++ b/device/barefoot/x86_64-accton_wedge100bf_65x-r0/mavericks/switch-sai.conf @@ -26,7 +26,7 @@ "tofino-bin": "share/tofinopd/switch/tofino.bin", "switchapi": "lib/libswitchapi.so", "switchsai": "lib/libswitchsai.so", - "agent0": "lib/mavericks/libpltfm_mgr.so", + "agent0": "lib/platform/x86_64-accton_wedge100bf_65x-r0/libpltfm_mgr.so", "switchapi_port_add": false } ] From e3ab940a62ac8a2b146944d29e935adaf72cf8dc Mon Sep 17 00:00:00 2001 From: kram Date: Fri, 5 Jan 2018 14:19:55 -0800 Subject: [PATCH 21/58] change source of files to github (from dropbox), update sairedis refpoint --- platform/barefoot/bfn-platform.mk | 2 +- platform/barefoot/bfn-sai.mk | 2 +- src/sonic-sairedis | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/platform/barefoot/bfn-platform.mk b/platform/barefoot/bfn-platform.mk index 7cc491921de4..b50a7d51c0f6 100644 --- a/platform/barefoot/bfn-platform.mk +++ b/platform/barefoot/bfn-platform.mk @@ -1,5 +1,5 @@ BFN_PLATFORM = bfnplatform_1.0.0_amd64.deb -$(BFN_PLATFORM)_URL = "https://www.dropbox.com/s/pname82eqzwbrcd/bfnplatform_1.0.0_amd64.deb?dl=0" +$(BFN_PLATFORM)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/rel_7_0/bfnplatform_1.0.0_amd64.deb" SONIC_ONLINE_DEBS += $(BFN_PLATFORM) # $(BFN_SAI_DEV) $(BFN_SAI_DEV)_DEPENDS += $(BFN_PLATFORM) diff --git a/platform/barefoot/bfn-sai.mk b/platform/barefoot/bfn-sai.mk index 4f27a7ae18c4..a23efaa44a19 100644 --- a/platform/barefoot/bfn-sai.mk +++ b/platform/barefoot/bfn-sai.mk @@ -1,5 +1,5 @@ BFN_SAI = bfnsdk_1.0.0_amd64.deb -$(BFN_SAI)_URL = "https://www.dropbox.com/s/4ljk6hzw82rudsr/bfnsdk_1.0.0_amd64.deb?dl=0" +$(BFN_SAI)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/rel_7_0/bfnsdk_1.0.0_amd64.deb" # $(BFN_SAI_DEV)_URL = "https://www.dropbox.com/s/4ljk6hzw82rudsr/bfnsdk_1.0.0_amd64.deb?dl=0" SONIC_ONLINE_DEBS += $(BFN_SAI) # $(BFN_SAI_DEV) diff --git a/src/sonic-sairedis b/src/sonic-sairedis index ce8028239b25..05048cff147b 160000 --- a/src/sonic-sairedis +++ b/src/sonic-sairedis @@ -1 +1 @@ -Subproject commit ce8028239b2595e8f42c8c1af573a5444c617513 +Subproject commit 05048cff147b2147c1f00d5aa4f60a877f4d6924 From 7d13a23412380e17466610476af96950514b4549 Mon Sep 17 00:00:00 2001 From: kram Date: Fri, 5 Jan 2018 15:57:02 -0800 Subject: [PATCH 22/58] update refpoint of sairedis --- src/sonic-sairedis | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-sairedis b/src/sonic-sairedis index 05048cff147b..450ed3bc3f36 160000 --- a/src/sonic-sairedis +++ b/src/sonic-sairedis @@ -1 +1 @@ -Subproject commit 05048cff147b2147c1f00d5aa4f60a877f4d6924 +Subproject commit 450ed3bc3f360bf6fe9b66c1e8b34b19cbcc296a From 6998c2113b5e8c6f3d15621bad3e4f011c9dbe80 Mon Sep 17 00:00:00 2001 From: kram Date: Fri, 12 Jan 2018 10:07:06 -0800 Subject: [PATCH 23/58] update sairedis (fast-boot refpoint) --- src/sonic-sairedis | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-sairedis b/src/sonic-sairedis index 450ed3bc3f36..2da73f89ee85 160000 --- a/src/sonic-sairedis +++ b/src/sonic-sairedis @@ -1 +1 @@ -Subproject commit 450ed3bc3f360bf6fe9b66c1e8b34b19cbcc296a +Subproject commit 2da73f89ee857dc337d18cdc92ed2042623cbed2 From 176c8c58cb23e9fea1f07d25e507d33f097f4bd1 Mon Sep 17 00:00:00 2001 From: kram Date: Wed, 17 Jan 2018 17:26:24 -0800 Subject: [PATCH 24/58] fix syncd rpc make files --- Makefile | 1 - platform/barefoot/docker-syncd-bfn-rpc/Dockerfile.j2 | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index d1a28f031748..025992aad547 100644 --- a/Makefile +++ b/Makefile @@ -57,7 +57,6 @@ SONIC_BUILD_INSTRUCTION := make \ BUILD_NUMBER=$(BUILD_NUMBER) \ ENABLE_DHCP_GRAPH_SERVICE=$(ENABLE_DHCP_GRAPH_SERVICE) \ SHUTDOWN_BGP_ON_START=$(SHUTDOWN_BGP_ON_START) \ - ENABLE_SYNCD_RPC=$(ENABLE_SYNCD_RPC) \ PASSWORD=$(PASSWORD) \ USERNAME=$(USERNAME) diff --git a/platform/barefoot/docker-syncd-bfn-rpc/Dockerfile.j2 b/platform/barefoot/docker-syncd-bfn-rpc/Dockerfile.j2 index 590f80aacde3..9efeeb3f6b51 100644 --- a/platform/barefoot/docker-syncd-bfn-rpc/Dockerfile.j2 +++ b/platform/barefoot/docker-syncd-bfn-rpc/Dockerfile.j2 @@ -4,7 +4,7 @@ FROM docker-syncd-bfn ENV DEBIAN_FRONTEND=noninteractive COPY \ -{% for deb in docker_syncd_bfn.split(' ') -%} +{% for deb in docker_syncd_bfn_rpc_debs.split(' ') -%} debs/{{ deb }}{{' '}} {%- endfor -%} debs/ @@ -12,7 +12,7 @@ debs/ RUN dpkg -P syncd RUN dpkg_apt() { [ -f $1 ] && { dpkg -i $1 || apt-get -y install -f; } || return 1; } ; \ -{% for deb in docker_syncd_bfn.split(' ') -%} +{% for deb in docker_syncd_bfn_rpc_debs.split(' ') -%} dpkg_apt debs/{{ deb }}{{'; '}} {%- endfor %} From 4dfca905f1cf499132e4c8572e73d18d6e30542d Mon Sep 17 00:00:00 2001 From: kram Date: Wed, 17 Jan 2018 17:27:51 -0800 Subject: [PATCH 25/58] update refpoint to handle Makefile change (no functional change) --- src/sonic-sairedis | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-sairedis b/src/sonic-sairedis index 2da73f89ee85..d6b0ca34fcf6 160000 --- a/src/sonic-sairedis +++ b/src/sonic-sairedis @@ -1 +1 @@ -Subproject commit 2da73f89ee857dc337d18cdc92ed2042623cbed2 +Subproject commit d6b0ca34fcf63d0b79c801cd95d7ee2fe58d21ac From 6a42e777e1f9a0cc05f3cfff3e1f563e8eac8ee0 Mon Sep 17 00:00:00 2001 From: kram Date: Thu, 18 Jan 2018 20:48:24 -0800 Subject: [PATCH 26/58] update refpoint for Makefile chnage in sairedis --- src/sonic-sairedis | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-sairedis b/src/sonic-sairedis index d6b0ca34fcf6..adfdb8642fe0 160000 --- a/src/sonic-sairedis +++ b/src/sonic-sairedis @@ -1 +1 @@ -Subproject commit d6b0ca34fcf63d0b79c801cd95d7ee2fe58d21ac +Subproject commit adfdb8642fe0b5dbb4e19d13871172a03a8c883b From fdbb3a65f66c2d3d6898bdc683c556a7d8a6595a Mon Sep 17 00:00:00 2001 From: kram Date: Fri, 19 Jan 2018 16:18:05 -0800 Subject: [PATCH 27/58] update refpoint - sairedis --- src/sonic-sairedis | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-sairedis b/src/sonic-sairedis index d6b0ca34fcf6..adfdb8642fe0 160000 --- a/src/sonic-sairedis +++ b/src/sonic-sairedis @@ -1 +1 @@ -Subproject commit d6b0ca34fcf63d0b79c801cd95d7ee2fe58d21ac +Subproject commit adfdb8642fe0b5dbb4e19d13871172a03a8c883b From c47c409a3ada50be452b8e1ebad101cf96b40302 Mon Sep 17 00:00:00 2001 From: kram Date: Fri, 19 Jan 2018 19:01:47 -0800 Subject: [PATCH 28/58] update sairedis to older refpoint till we debug clean build --- src/sonic-sairedis | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-sairedis b/src/sonic-sairedis index adfdb8642fe0..2da73f89ee85 160000 --- a/src/sonic-sairedis +++ b/src/sonic-sairedis @@ -1 +1 @@ -Subproject commit adfdb8642fe0b5dbb4e19d13871172a03a8c883b +Subproject commit 2da73f89ee857dc337d18cdc92ed2042623cbed2 From 8da1f5ca08f13ba0e0a61637a9a4cb8ea200ac4b Mon Sep 17 00:00:00 2001 From: kram Date: Tue, 23 Jan 2018 11:30:17 -0800 Subject: [PATCH 29/58] export asic platform for build --- slave.mk | 1 + 1 file changed, 1 insertion(+) diff --git a/slave.mk b/slave.mk index 8ec6832bd687..301d72bb8d12 100644 --- a/slave.mk +++ b/slave.mk @@ -31,6 +31,7 @@ PROJECT_ROOT = $(shell pwd) CONFIGURED_PLATFORM := $(shell [ -f .platform ] && cat .platform || echo generic) PLATFORM_PATH = platform/$(CONFIGURED_PLATFORM) export BUILD_NUMBER +export CONFIGURED_PLATFORM ############################################################################### ## Utility rules From 3709499283f12c7864c43f5018177fa809265ec0 Mon Sep 17 00:00:00 2001 From: kram Date: Tue, 23 Jan 2018 11:52:13 -0800 Subject: [PATCH 30/58] update refpoint for makefiles --- src/sonic-sairedis | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-sairedis b/src/sonic-sairedis index 2da73f89ee85..fb55ef78e5ec 160000 --- a/src/sonic-sairedis +++ b/src/sonic-sairedis @@ -1 +1 @@ -Subproject commit 2da73f89ee857dc337d18cdc92ed2042623cbed2 +Subproject commit fb55ef78e5ec624d54bebe5f60ccdea94e5940b0 From 847149907777f1ec754a394d2264d195ea1cc7be Mon Sep 17 00:00:00 2001 From: Brand Date: Fri, 26 Jan 2018 16:44:02 +0800 Subject: [PATCH 31/58] Upload wnc-osw1800 --- .../OSW1800-48x6q/port_config.ini | 55 + .../OSW1800-48x6q/switch-sai.conf | 33 + device/wnc/x86_64-wnc_osw1800-r0/fancontrol | 11 + .../wnc/x86_64-wnc_osw1800-r0/installer.conf | 3 + .../wnc/x86_64-wnc_osw1800-r0/minigraph.xml | 1761 ++++++++++++ .../x86_64-wnc_osw1800-r0/plugins/eeprom.py | 22 + .../x86_64-wnc_osw1800-r0/plugins/psuutil.py | 64 + .../x86_64-wnc_osw1800-r0/plugins/sfputil.py | 205 ++ device/wnc/x86_64-wnc_osw1800-r0/sensors.conf | 33 + platform/barefoot/bfn-platform.mk | 2 +- platform/barefoot/bfn-sai.mk | 2 +- platform/barefoot/one-image.mk | 5 +- .../barefoot/platform-modules-wnc-osw1800.mk | 11 + platform/barefoot/rules.mk | 1 + .../LICENSE | 15 + .../MAINTAINERS | 7 + .../README.md | 2 + .../debian/changelog | 5 + .../debian/compat | 1 + .../debian/control | 12 + .../debian/copyright | 15 + .../debian/files | 1 + .../debian/rules | 38 + .../modules/Makefile | 6 + .../modules/bf_kdrv.c | 1249 +++++++++ .../modules/bf_tun.c | 2396 +++++++++++++++++ .../modules/i2c-mcp2221.c | 611 +++++ .../modules/wnc_cpld.c | 198 ++ .../modules/wnc_cpld3.c | 200 ++ .../modules/wnc_eeprom.c | 286 ++ .../scripts/device_node.sh | 91 + .../scripts/driver_load.sh | 50 + .../scripts/test | 1 + .../service/device_node.service | 11 + .../service/driver_load.service | 10 + 35 files changed, 7409 insertions(+), 4 deletions(-) create mode 100644 device/wnc/x86_64-wnc_osw1800-r0/OSW1800-48x6q/port_config.ini create mode 100644 device/wnc/x86_64-wnc_osw1800-r0/OSW1800-48x6q/switch-sai.conf create mode 100644 device/wnc/x86_64-wnc_osw1800-r0/fancontrol create mode 100644 device/wnc/x86_64-wnc_osw1800-r0/installer.conf create mode 100644 device/wnc/x86_64-wnc_osw1800-r0/minigraph.xml create mode 100644 device/wnc/x86_64-wnc_osw1800-r0/plugins/eeprom.py create mode 100644 device/wnc/x86_64-wnc_osw1800-r0/plugins/psuutil.py create mode 100644 device/wnc/x86_64-wnc_osw1800-r0/plugins/sfputil.py create mode 100644 device/wnc/x86_64-wnc_osw1800-r0/sensors.conf create mode 100644 platform/barefoot/platform-modules-wnc-osw1800.mk create mode 100644 platform/barefoot/sonic-platform-modules-wnc-osw1800/LICENSE create mode 100644 platform/barefoot/sonic-platform-modules-wnc-osw1800/MAINTAINERS create mode 100644 platform/barefoot/sonic-platform-modules-wnc-osw1800/README.md create mode 100644 platform/barefoot/sonic-platform-modules-wnc-osw1800/debian/changelog create mode 100644 platform/barefoot/sonic-platform-modules-wnc-osw1800/debian/compat create mode 100644 platform/barefoot/sonic-platform-modules-wnc-osw1800/debian/control create mode 100644 platform/barefoot/sonic-platform-modules-wnc-osw1800/debian/copyright create mode 100644 platform/barefoot/sonic-platform-modules-wnc-osw1800/debian/files create mode 100755 platform/barefoot/sonic-platform-modules-wnc-osw1800/debian/rules create mode 100644 platform/barefoot/sonic-platform-modules-wnc-osw1800/modules/Makefile create mode 100644 platform/barefoot/sonic-platform-modules-wnc-osw1800/modules/bf_kdrv.c create mode 100644 platform/barefoot/sonic-platform-modules-wnc-osw1800/modules/bf_tun.c create mode 100644 platform/barefoot/sonic-platform-modules-wnc-osw1800/modules/i2c-mcp2221.c create mode 100644 platform/barefoot/sonic-platform-modules-wnc-osw1800/modules/wnc_cpld.c create mode 100644 platform/barefoot/sonic-platform-modules-wnc-osw1800/modules/wnc_cpld3.c create mode 100644 platform/barefoot/sonic-platform-modules-wnc-osw1800/modules/wnc_eeprom.c create mode 100644 platform/barefoot/sonic-platform-modules-wnc-osw1800/scripts/device_node.sh create mode 100644 platform/barefoot/sonic-platform-modules-wnc-osw1800/scripts/driver_load.sh create mode 100644 platform/barefoot/sonic-platform-modules-wnc-osw1800/scripts/test create mode 100644 platform/barefoot/sonic-platform-modules-wnc-osw1800/service/device_node.service create mode 100644 platform/barefoot/sonic-platform-modules-wnc-osw1800/service/driver_load.service diff --git a/device/wnc/x86_64-wnc_osw1800-r0/OSW1800-48x6q/port_config.ini b/device/wnc/x86_64-wnc_osw1800-r0/OSW1800-48x6q/port_config.ini new file mode 100644 index 000000000000..f47ac7345b6c --- /dev/null +++ b/device/wnc/x86_64-wnc_osw1800-r0/OSW1800-48x6q/port_config.ini @@ -0,0 +1,55 @@ +# name lanes alias speed autoneg fec +Ethernet0 0 Ethernet0 25000 1 1 +Ethernet4 1 Ethernet4 25000 1 1 +Ethernet8 2 Ethernet8 25000 1 1 +Ethernet12 3 Ethernet12 25000 1 1 +Ethernet16 4 Ethernet16 25000 1 1 +Ethernet20 5 Ethernet20 25000 1 1 +Ethernet24 6 Ethernet24 25000 1 1 +Ethernet28 7 Ethernet28 25000 1 1 +Ethernet32 8 Ethernet32 25000 1 1 +Ethernet36 9 Ethernet36 25000 1 1 +Ethernet40 10 Ethernet40 25000 1 1 +Ethernet44 11 Ethernet44 25000 1 1 +Ethernet48 12 Ethernet48 25000 1 1 +Ethernet52 13 Ethernet52 25000 1 1 +Ethernet56 14 Ethernet56 25000 1 1 +Ethernet60 15 Ethernet60 25000 1 1 +Ethernet64 16 Ethernet64 25000 1 1 +Ethernet68 17 Ethernet68 25000 1 1 +Ethernet72 18 Ethernet72 25000 1 1 +Ethernet76 19 Ethernet76 25000 1 1 +Ethernet80 20 Ethernet80 25000 1 1 +Ethernet84 21 Ethernet84 25000 1 1 +Ethernet88 22 Ethernet88 25000 1 1 +Ethernet92 23 Ethernet92 25000 1 1 +Ethernet96 24 Ethernet96 25000 1 1 +Ethernet100 25 Ethernet100 25000 1 1 +Ethernet104 26 Ethernet104 25000 1 1 +Ethernet108 27 Ethernet108 25000 1 1 +Ethernet112 28 Ethernet112 25000 1 1 +Ethernet116 29 Ethernet116 25000 1 1 +Ethernet120 30 Ethernet120 25000 1 1 +Ethernet124 31 Ethernet124 25000 1 1 +Ethernet128 32 Ethernet128 25000 1 1 +Ethernet132 33 Ethernet132 25000 1 1 +Ethernet136 34 Ethernet136 25000 1 1 +Ethernet140 35 Ethernet140 25000 1 1 +Ethernet144 36 Ethernet144 25000 1 1 +Ethernet148 37 Ethernet148 25000 1 1 +Ethernet152 38 Ethernet152 25000 1 1 +Ethernet156 39 Ethernet156 25000 1 1 +Ethernet160 40 Ethernet160 25000 1 1 +Ethernet164 41 Ethernet164 25000 1 1 +Ethernet168 42 Ethernet168 25000 1 1 +Ethernet172 43 Ethernet172 25000 1 1 +Ethernet176 44 Ethernet176 25000 1 1 +Ethernet180 45 Ethernet180 25000 1 1 +Ethernet184 46 Ethernet184 25000 1 1 +Ethernet188 47 Ethernet188 25000 1 1 +Ethernet192 48,49,50,51 Ethernet192 100000 1 1 +Ethernet196 52,53,54,55 Ethernet196 100000 1 1 +Ethernet200 56,57,58,59 Ethernet200 100000 1 1 +Ethernet204 60,61,62,63 Ethernet204 100000 1 1 +Ethernet208 64,65,66,67 Ethernet208 100000 1 1 +Ethernet212 68,69,70,71 Ethernet212 100000 1 1 diff --git a/device/wnc/x86_64-wnc_osw1800-r0/OSW1800-48x6q/switch-sai.conf b/device/wnc/x86_64-wnc_osw1800-r0/OSW1800-48x6q/switch-sai.conf new file mode 100644 index 000000000000..65a02a621f03 --- /dev/null +++ b/device/wnc/x86_64-wnc_osw1800-r0/OSW1800-48x6q/switch-sai.conf @@ -0,0 +1,33 @@ +{ + "chip_list": [ + { + "id": "asic-0", + "chip_family": "Tofino", + "instance": 0, + "pcie_sysfs_prefix": "/sys/devices/pci0000:00/0000:00:03.0/0000:05:00.0", + "pcie_domain": 0, + "pcie_bus": 5, + "pcie_fn": 0, + "pcie_dev": 0, + "pcie_int_mode": 1, + "sds_fw_path": "share/tofino_sds_fw/avago/firmware" + } + ], + "instance": 0, + "p4_program_list": [ + { + "id": "pgm-0", + "instance": 0, + "path": "switch", + "program-name": "switch", + "pd": "lib/tofinopd/switch/libpd.so", + "pd-thrift": "lib/tofinopd/switch/libpdthrift.so", + "table-config": "share/tofinopd/switch/context.json", + "tofino-bin": "share/tofinopd/switch/tofino.bin", + "switchapi": "lib/libswitchapi.so", + "switchsai": "lib/libswitchsai.so", + "agent0": "lib/platform/x86_64-wnc_osw1800-r0/libpltfm_mgr.so", + "switchapi_port_add": false + } + ] +} diff --git a/device/wnc/x86_64-wnc_osw1800-r0/fancontrol b/device/wnc/x86_64-wnc_osw1800-r0/fancontrol new file mode 100644 index 000000000000..d661bd11f1b2 --- /dev/null +++ b/device/wnc/x86_64-wnc_osw1800-r0/fancontrol @@ -0,0 +1,11 @@ +INTERVAL=10 +DEVPATH=hwmon1=devices/pci0000:00/0000:00:16.0/usb1/1-1/1-1.2/1-1.2.3/1-1.2.3:1.2/i2c-2/i2c-5/5-0033 hwmon2=devices/pci0000:00/0000:00:16.0/usb1/1-1/1-1.2/1-1.2.3/1-1.2.3:1.2/i2c-2/i2c-7/7-001e hwmon3=devices/pci0000:00/0000:00:16.0/usb1/1-1/1-1.2/1-1.2.3/1-1.2.3:1.2/i2c-2/i2c-7/7-004e hwmon4=devices/pci0000:00/0000:00:16.0/usb1/1-1/1-1.2/1-1.2.3/1-1.2.3:1.2/i2c-2/i2c-7/7-004f +DEVNAME=hwmon1=wnc_cpld3 hwmon2=tmp421 hwmon3=tmp75 hwmon4=tmp421 +FCTEMPS=hwmon1/pwm1=hwmon2/temp1_input hwmon1/pwm2=hwmon2/temp2_input hwmon1/pwm3=hwmon3/temp1_input hwmon1/pwm4=hwmon4/temp1_input hwmon1/pwm5=hwmon4/temp2_input +FCFANS=hwmon1/pwm1=hwmon1/fan1_input hwmon1/pwm2=hwmon1/fan2_input hwmon1/pwm3=hwmon1/fan3_input hwmon1/pwm4=hwmon1/fan4_input hwmon1/pwm5=hwmon1/fan5_input +MINTEMP=hwmon1/pwm1=20 hwmon1/pwm2=20 hwmon1/pwm3=20 hwmon1/pwm4=20 hwmon1/pwm5=20 +MAXTEMP=hwmon1/pwm1=50 hwmon1/pwm2=50 hwmon1/pwm3=50 hwmon1/pwm4=50 hwmon1/pwm5=50 +MINSTART=hwmon1/pwm1=32 hwmon1/pwm2=32 hwmon1/pwm3=32 hwmon1/pwm4=32 hwmon1/pwm5=32 +MINSTOP=hwmon1/pwm1=22 hwmon1/pwm2=22 hwmon1/pwm3=22 hwmon1/pwm4=22 hwmon1/pwm5=22 +MINPWM=hwmon1/pwm1=10 hwmon1/pwm2=10 hwmon1/pwm3=10 hwmon1/pwm4=10 hwmon1/pwm5=10 +MAXPWM=hwmon1/pwm1=100 hwmon1/pwm2=100 hwmon1/pwm3=100 hwmon1/pwm4=100 hwmon1/pwm5=100 diff --git a/device/wnc/x86_64-wnc_osw1800-r0/installer.conf b/device/wnc/x86_64-wnc_osw1800-r0/installer.conf new file mode 100644 index 000000000000..dfa6df22689b --- /dev/null +++ b/device/wnc/x86_64-wnc_osw1800-r0/installer.conf @@ -0,0 +1,3 @@ +CONSOLE_PORT=0x2f8 +CONSOLE_DEV=1 +CONSOLE_SPEED=57600 diff --git a/device/wnc/x86_64-wnc_osw1800-r0/minigraph.xml b/device/wnc/x86_64-wnc_osw1800-r0/minigraph.xml new file mode 100644 index 000000000000..fc4dcee3058e --- /dev/null +++ b/device/wnc/x86_64-wnc_osw1800-r0/minigraph.xml @@ -0,0 +1,1761 @@ + + + + + + ARISTA01T0 + 10.0.0.55 + switch2 + 10.0.0.54 + 1 + 180 + 60 + + + switch2 + 10.0.0.0 + ARISTA01T2 + 10.0.0.1 + 1 + 180 + 60 + + + ARISTA02T0 + 10.0.0.57 + switch2 + 10.0.0.56 + 1 + 180 + 60 + + + switch2 + 10.0.0.2 + ARISTA02T2 + 10.0.0.3 + 1 + 180 + 60 + + + ARISTA03T0 + 10.0.0.59 + switch2 + 10.0.0.58 + 1 + 180 + 60 + + + switch2 + 10.0.0.4 + ARISTA03T2 + 10.0.0.5 + 1 + 180 + 60 + + + ARISTA04T0 + 10.0.0.61 + switch2 + 10.0.0.60 + 1 + 180 + 60 + + + switch2 + 10.0.0.6 + ARISTA04T2 + 10.0.0.7 + 1 + 180 + 60 + + + ARISTA05T0 + 10.0.0.63 + switch2 + 10.0.0.62 + 1 + 180 + 60 + + + switch2 + 10.0.0.8 + ARISTA05T2 + 10.0.0.9 + 1 + 180 + 60 + + + ARISTA06T0 + 10.0.0.65 + switch2 + 10.0.0.64 + 1 + 180 + 60 + + + switch2 + 10.0.0.10 + ARISTA06T2 + 10.0.0.11 + 1 + 180 + 60 + + + ARISTA07T0 + 10.0.0.67 + switch2 + 10.0.0.66 + 1 + 180 + 60 + + + switch2 + 10.0.0.12 + ARISTA07T2 + 10.0.0.13 + 1 + 180 + 60 + + + ARISTA08T0 + 10.0.0.69 + switch2 + 10.0.0.68 + 1 + 180 + 60 + + + switch2 + 10.0.0.14 + ARISTA08T2 + 10.0.0.15 + 1 + 180 + 60 + + + ARISTA09T0 + 10.0.0.71 + switch2 + 10.0.0.70 + 1 + 180 + 60 + + + switch2 + 10.0.0.16 + ARISTA09T2 + 10.0.0.17 + 1 + 180 + 60 + + + ARISTA10T0 + 10.0.0.73 + switch2 + 10.0.0.72 + 1 + 180 + 60 + + + switch2 + 10.0.0.18 + ARISTA10T2 + 10.0.0.19 + 1 + 180 + 60 + + + ARISTA11T0 + 10.0.0.75 + switch2 + 10.0.0.74 + 1 + 180 + 60 + + + switch2 + 10.0.0.20 + ARISTA11T2 + 10.0.0.21 + 1 + 180 + 60 + + + ARISTA12T0 + 10.0.0.77 + switch2 + 10.0.0.76 + 1 + 180 + 60 + + + switch2 + 10.0.0.22 + ARISTA12T2 + 10.0.0.23 + 1 + 180 + 60 + + + ARISTA13T0 + 10.0.0.79 + switch2 + 10.0.0.78 + 1 + 180 + 60 + + + switch2 + 10.0.0.24 + ARISTA13T2 + 10.0.0.25 + 1 + 180 + 60 + + + ARISTA14T0 + 10.0.0.81 + switch2 + 10.0.0.80 + 1 + 180 + 60 + + + switch2 + 10.0.0.26 + ARISTA14T2 + 10.0.0.27 + 1 + 180 + 60 + + + ARISTA15T0 + 10.0.0.83 + switch2 + 10.0.0.82 + 1 + 180 + 60 + + + switch2 + 10.0.0.28 + ARISTA15T2 + 10.0.0.29 + 1 + 180 + 60 + + + ARISTA16T0 + 10.0.0.85 + switch2 + 10.0.0.84 + 1 + 180 + 60 + + + switch2 + 10.0.0.30 + ARISTA16T2 + 10.0.0.31 + 1 + 180 + 60 + + + ARISTA17T0 + 10.0.0.87 + switch2 + 10.0.0.86 + 1 + 180 + 60 + + + switch2 + 10.0.0.32 + ARISTA17T2 + 10.0.0.33 + 1 + 180 + 60 + + + ARISTA18T0 + 10.0.0.89 + switch2 + 10.0.0.88 + 1 + 180 + 60 + + + switch2 + 10.0.0.34 + ARISTA18T2 + 10.0.0.35 + 1 + 180 + 60 + + + ARISTA19T0 + 10.0.0.91 + switch2 + 10.0.0.90 + 1 + 180 + 60 + + + switch2 + 10.0.0.36 + ARISTA19T2 + 10.0.0.37 + 1 + 180 + 60 + + + ARISTA20T0 + 10.0.0.93 + switch2 + 10.0.0.92 + 1 + 180 + 60 + + + switch2 + 10.0.0.38 + ARISTA20T2 + 10.0.0.39 + 1 + 180 + 60 + + + ARISTA21T0 + 10.0.0.95 + switch2 + 10.0.0.94 + 1 + 180 + 60 + + + switch2 + 10.0.0.40 + ARISTA21T2 + 10.0.0.41 + 1 + 180 + 60 + + + ARISTA22T0 + 10.0.0.97 + switch2 + 10.0.0.96 + 1 + 180 + 60 + + + switch2 + 10.0.0.42 + ARISTA22T2 + 10.0.0.43 + 1 + 180 + 60 + + + ARISTA23T0 + 10.0.0.99 + switch2 + 10.0.0.98 + 1 + 180 + 60 + + + switch2 + 10.0.0.44 + ARISTA23T2 + 10.0.0.45 + 1 + 180 + 60 + + + ARISTA24T0 + 10.0.0.101 + switch2 + 10.0.0.100 + 1 + 180 + 60 + + + switch2 + 10.0.0.46 + ARISTA24T2 + 10.0.0.47 + 1 + 180 + 60 + + + ARISTA25T0 + 10.0.0.103 + switch2 + 10.0.0.102 + 1 + 180 + 60 + + + switch2 + 10.0.0.48 + ARISTA25T2 + 10.0.0.49 + 1 + 180 + 60 + + + ARISTA26T0 + 10.0.0.105 + switch2 + 10.0.0.104 + 1 + 180 + 60 + + + switch2 + 10.0.0.50 + ARISTA26T2 + 10.0.0.51 + 1 + 180 + 60 + + + ARISTA27T0 + 10.0.0.107 + switch2 + 10.0.0.106 + 1 + 180 + 60 + + + switch2 + 10.0.0.52 + ARISTA27T2 + 10.0.0.53 + 1 + 180 + 60 + + + + + 65100 + switch2 + + +
10.0.0.55
+ + +
+ +
10.0.0.1
+ + +
+ +
10.0.0.57
+ + +
+ +
10.0.0.3
+ + +
+ +
10.0.0.59
+ + +
+ +
10.0.0.5
+ + +
+ +
10.0.0.61
+ + +
+ +
10.0.0.7
+ + +
+ +
10.0.0.63
+ + +
+ +
10.0.0.9
+ + +
+ +
10.0.0.65
+ + +
+ +
10.0.0.11
+ + +
+ +
10.0.0.67
+ + +
+ +
10.0.0.13
+ + +
+ +
10.0.0.69
+ + +
+ +
10.0.0.15
+ + +
+ +
10.0.0.71
+ + +
+ +
10.0.0.17
+ + +
+ +
10.0.0.73
+ + +
+ +
10.0.0.19
+ + +
+ +
10.0.0.75
+ + +
+ +
10.0.0.21
+ + +
+ +
10.0.0.77
+ + +
+ +
10.0.0.23
+ + +
+ +
10.0.0.79
+ + +
+ +
10.0.0.25
+ + +
+ +
10.0.0.81
+ + +
+ +
10.0.0.27
+ + +
+ +
10.0.0.83
+ + +
+ +
10.0.0.29
+ + +
+ +
10.0.0.85
+ + +
+ +
10.0.0.31
+ + +
+ +
10.0.0.87
+ + +
+ +
10.0.0.33
+ + +
+ +
10.0.0.89
+ + +
+ +
10.0.0.35
+ + +
+ +
10.0.0.91
+ + +
+ +
10.0.0.37
+ + +
+ +
10.0.0.93
+ + +
+ +
10.0.0.39
+ + +
+ +
10.0.0.95
+ + +
+ +
10.0.0.41
+ + +
+ +
10.0.0.97
+ + +
+ +
10.0.0.43
+ + +
+ +
10.0.0.99
+ + +
+ +
10.0.0.45
+ + +
+ +
10.0.0.101
+ + +
+ +
10.0.0.47
+ + +
+ +
10.0.0.103
+ + +
+ +
10.0.0.49
+ + +
+ +
10.0.0.105
+ + +
+ +
10.0.0.51
+ + +
+ +
10.0.0.107
+ + +
+ +
10.0.0.53
+ + +
+
+ +
+ + 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 + + + + 64016 + ARISTA17T0 + + + + 65200 + ARISTA17T2 + + + + 64016 + ARISTA18T0 + + + + 65200 + ARISTA18T2 + + + + 64016 + ARISTA19T0 + + + + 65200 + ARISTA19T2 + + + + 64016 + ARISTA20T0 + + + + 65200 + ARISTA20T2 + + + + 64016 + ARISTA21T0 + + + + 65200 + ARISTA21T2 + + + + 64016 + ARISTA22T0 + + + + 65200 + ARISTA22T2 + + + + 64016 + ARISTA23T0 + + + + 65200 + ARISTA23T2 + + + + 64016 + ARISTA24T0 + + + + 65200 + ARISTA24T2 + + + + 64016 + ARISTA25T0 + + + + 65200 + ARISTA25T2 + + + + 64016 + ARISTA26T0 + + + + 65200 + ARISTA26T2 + + + + 64016 + ARISTA27T0 + + + + 65200 + ARISTA27T2 + + +
+
+ + + + + + HostIP + Loopback0 + + 10.1.0.32/32 + + 10.1.0.32/32 + + + + + + + + switch2 + + + + + + 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 + + + + Ethernet128 + 10.0.0.64/31 + + + + Ethernet132 + 10.0.0.66/31 + + + + Ethernet136 + 10.0.0.68/31 + + + + Ethernet140 + 10.0.0.70/31 + + + + Ethernet144 + 10.0.0.72/31 + + + + Ethernet148 + 10.0.0.74/31 + + + + Ethernet152 + 10.0.0.76/31 + + + + Ethernet156 + 10.0.0.78/31 + + + + Ethernet160 + 10.0.0.80/31 + + + + Ethernet164 + 10.0.0.82/31 + + + + Ethernet168 + 10.0.0.84/31 + + + + Ethernet172 + 10.0.0.86/31 + + + + Ethernet176 + 10.0.0.88/31 + + + + Ethernet180 + 10.0.0.90/31 + + + + Ethernet184 + 10.0.0.92/31 + + + + Ethernet188 + 10.0.0.94/31 + + + + Ethernet192 + 10.0.0.96/31 + + + + Ethernet196 + 10.0.0.98/31 + + + + Ethernet200 + 10.0.0.100/31 + + + + Ethernet204 + 10.0.0.102/31 + + + + Ethernet208 + 10.0.0.104/31 + + + + Ethernet212 + 10.0.0.106/31 + + + + + + + + + + + + DeviceInterfaceLink + switch2 + Ethernet0 + ARISTA01T2 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet4 + ARISTA02T2 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet8 + ARISTA03T2 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet12 + ARISTA04T2 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet16 + ARISTA05T2 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet20 + ARISTA06T2 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet24 + ARISTA07T2 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet28 + ARISTA08T2 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet32 + ARISTA09T2 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet36 + ARISTA10T2 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet40 + ARISTA11T2 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet44 + ARISTA12T2 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet48 + ARISTA13T2 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet52 + ARISTA14T2 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet56 + ARISTA15T2 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet60 + ARISTA16T2 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet64 + ARISTA17T2 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet68 + ARISTA18T2 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet72 + ARISTA19T2 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet76 + ARISTA20T2 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet80 + ARISTA21T2 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet84 + ARISTA22T2 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet88 + ARISTA23T2 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet92 + ARISTA24T2 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet96 + ARISTA25T2 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet100 + ARISTA26T2 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet104 + ARISTA27T2 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet108 + ARISTA01T0 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet112 + ARISTA02T0 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet116 + ARISTA03T0 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet120 + ARISTA04T0 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet124 + ARISTA05T0 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet128 + ARISTA06T0 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet132 + ARISTA07T0 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet136 + ARISTA08T0 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet140 + ARISTA09T0 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet144 + ARISTA10T0 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet148 + ARISTA11T0 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet152 + ARISTA12T0 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet156 + ARISTA13T0 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet160 + ARISTA14T0 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet164 + ARISTA15T0 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet168 + ARISTA16T0 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet172 + ARISTA17T0 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet176 + ARISTA18T0 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet180 + ARISTA19T0 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet184 + ARISTA20T0 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet188 + ARISTA21T0 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet192 + ARISTA22T0 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet196 + ARISTA23T0 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet200 + ARISTA24T0 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet204 + ARISTA25T0 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet208 + ARISTA26T0 + Ethernet1 + + + DeviceInterfaceLink + switch2 + Ethernet212 + ARISTA27T0 + Ethernet1 + + + + + switch2 + OSW1800-48x6q + + + + + + + switch2 + + + DhcpResources + + 192.168.1.111 + + + NtpResources + + 0.debian.pool.ntp.org;1.debian.pool.ntp.org;2.debian.pool.ntp.org;3.debian.pool.ntp.org + + + SyslogResources + + 192.0.0.1 + + + ErspanDestinationIpv4 + + 2.2.2.2 + + + + + + + switch2 + OSW1800-48x6q +
diff --git a/device/wnc/x86_64-wnc_osw1800-r0/plugins/eeprom.py b/device/wnc/x86_64-wnc_osw1800-r0/plugins/eeprom.py new file mode 100644 index 000000000000..a073374794fa --- /dev/null +++ b/device/wnc/x86_64-wnc_osw1800-r0/plugins/eeprom.py @@ -0,0 +1,22 @@ +#!/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 +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-8/8-0052/eeprom" + super(board, self).__init__(self.eeprom_path, 0, '', True) + diff --git a/device/wnc/x86_64-wnc_osw1800-r0/plugins/psuutil.py b/device/wnc/x86_64-wnc_osw1800-r0/plugins/psuutil.py new file mode 100644 index 000000000000..e62159c8a8cc --- /dev/null +++ b/device/wnc/x86_64-wnc_osw1800-r0/plugins/psuutil.py @@ -0,0 +1,64 @@ +# +# 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""" + + def __init__(self): + PsuBase.__init__(self) + + def get_num_psus(self): + return 2 + + def get_psu_status(self, index): + if index == 1: + psu_path = "/sys/bus/i2c/devices/6-0050/eeprom" + elif index == 2: + psu_path = "/sys/bus/i2c/devices/6-0051/eeprom" + else: + return False + + try: + data = open(psu_path, "rb") + except IOError: + return False + + result = int(data.read(1).encode("hex"), 16) + data.close() + + if result != 255 and result != 0: + return True + else: + return False + + def get_psu_presence(self, index): + if index == 1: + psu_path = "/sys/bus/i2c/devices/6-0050/eeprom" + elif index == 2: + psu_path = "/sys/bus/i2c/devices/6-0051/eeprom" + else: + return False + + try: + data = open(psu_path, "rb") + except IOError: + return False + + result = int(data.read(1).encode("hex"), 16) + data.close() + + if result != 255 and result != 0: + return True + else: + return False diff --git a/device/wnc/x86_64-wnc_osw1800-r0/plugins/sfputil.py b/device/wnc/x86_64-wnc_osw1800-r0/plugins/sfputil.py new file mode 100644 index 000000000000..1c1e86bc5d6e --- /dev/null +++ b/device/wnc/x86_64-wnc_osw1800-r0/plugins/sfputil.py @@ -0,0 +1,205 @@ +#! /usr/bin/python +# +# Platform-specific SFP transceiver interface for SONiC +# + +try: + import time + from sonic_sfp.sfputilbase import SfpUtilBase + import sys + sys.path.append('/usr/lib/python2.7/dist-packages/sonic_sfp/') + from sff8472 import sff8472InterfaceId + from sff8472 import sff8472Dom + from sff8436 import sff8436InterfaceId + from sff8436 import sff8436Dom +except ImportError, e: + raise ImportError("%s - required module not found" % str(e)) + + +class SfpUtil(SfpUtilBase): + """Platform-specific SfpUtil class""" + + PORT_START = 0 + PORT_END = 53 + PORTS_IN_BLOCK = 54 + + EEPROM_OFFSET = 11 + + _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(self.PORT_START + 48, self.PORTS_IN_BLOCK) + + @property + def port_to_eeprom_mapping(self): + return self._port_to_eeprom_mapping + + def __init__(self): + eeprom_path = "/sys/class/i2c-adapter/i2c-{0}/{0}-0050/eeprom" + + 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): + bit_mask = port_num % 8 + + if port_num <= 7: + presence_path = "/sys/bus/i2c/devices/3-0031/sfp_mod_abs1" + elif 8 <= port_num and port_num <= 15: + presence_path = "/sys/bus/i2c/devices/3-0031/sfp_mod_abs2" + elif 16 <= port_num and port_num <= 23: + presence_path = "/sys/bus/i2c/devices/3-0031/sfp_mod_abs3" + elif 24 <= port_num and port_num <= 27: + presence_path = "/sys/bus/i2c/devices/3-0031/sfp_mod_abs4" + elif 28 <= port_num and port_num <= 31: + presence_path = "/sys/bus/i2c/devices/4-0032/sfp_mod_abs1" + bit_mask = bit_mask - 4 + elif 32 <= port_num and port_num <= 39: + presence_path = "/sys/bus/i2c/devices/4-0032/sfp_mod_abs2" + elif 40 <= port_num and port_num <= 47: + presence_path = "/sys/bus/i2c/devices/4-0032/sfp_mod_abs3" + elif 48 <= port_num and port_num <= 71: + presence_path = "/sys/bus/i2c/devices/4-0032/qsfp_modprs" + else: + return False + + try: + reg_file = open(presence_path, "rb") + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + content = reg_file.readline().rstrip() + reg_value = int(content, 16) + reg_file.close() + + if reg_value & (1 << bit_mask) == 0: + return True + else: + return False + + def get_low_power_mode(self, port_num): + if port_num in self.qsfp_ports: + bit_mask = port_num % 8 + else: + return False + + try: + reg_file = open("/sys/bus/i2c/devices/4-0032/qsfp_lpmode") + except IOError as e: + print "Error: unable to open file: %s" % str(e) + + content = reg_file.readline().rstrip() + reg_value = int(content, 16) + reg_file.close() + + if reg_value & (1 << bit_mask) == 0: + return False + + return True + + def set_low_power_mode(self, port_num, lpmode): + if port_num in self.qsfp_ports: + bit_mask = port_num % 8 + else: + return False + + try: + reg_file = open("/sys/bus/i2c/devices/4-0032/qsfp_lpmode", "r+") + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + content = reg_file.readline().rstrip() + reg_value = int(content, 16) + + if lpmode is True: + reg_value = reg_value | (1 << bit_mask) + else: + reg_value = reg_value & ~(1 << bit_mask) + + reg_file.seek(0) + reg_file.write(str(reg_value)) + reg_file.close() + + return True + + def reset(self, port_num): + if port_num in self.qsfp_ports: + bit_mask = (port_num % 8) + 2 + else: + return False + + try: + reg_file = open("/sys/bus/i2c/devices/4-0032/reset_control", "r+") + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + content = reg_file.readline().rstrip() + reg_value = int(content, 16) + reg_value = reg_value & ~(1 << bit_mask) + + reg_file.seek(0) + reg_file.write(str(reg_value)) + reg_file.close() + + time.sleep(1) + + try: + reg_file = open("/sys/bus/i2c/devices/4-0032/reset_control", "w") + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + reg_value = reg_value | (1 << bit_mask) + reg_file.seek(0) + reg_file.write(str(reg_value)) + reg_file.close() + + return True + + def get_eeprom_dict(self, port_num): + if not self.get_presence(port_num): + return None + + sfp_data = {} + + eeprom_ifraw = self.get_eeprom_raw(port_num) + eeprom_domraw = self.get_eeprom_dom_raw(port_num) + + if eeprom_ifraw is None: + return None + + if port_num in self.qsfp_ports: + sfpi_obj = sff8436InterfaceId(eeprom_ifraw) + if sfpi_obj is not None: + sfp_data['interface'] = sfpi_obj.get_data_pretty() + + sfpd_obj = sff8436Dom(eeprom_ifraw) + if sfpd_obj is not None: + sfp_data['dom'] = sfpd_obj.get_data_pretty() + return sfp_data + + sfpi_obj = sff8472InterfaceId(eeprom_ifraw) + if sfpi_obj is not None: + sfp_data['interface'] = sfpi_obj.get_data_pretty() + cal_type = sfpi_obj.get_calibration_type() + + if eeprom_domraw is not None: + sfpd_obj = sff8472Dom(eeprom_domraw, cal_type) + if sfpd_obj is not None: + sfp_data['dom'] = sfpd_obj.get_data_pretty() + + return sfp_data diff --git a/device/wnc/x86_64-wnc_osw1800-r0/sensors.conf b/device/wnc/x86_64-wnc_osw1800-r0/sensors.conf new file mode 100644 index 000000000000..d91945ff722b --- /dev/null +++ b/device/wnc/x86_64-wnc_osw1800-r0/sensors.conf @@ -0,0 +1,33 @@ +# libsensors configuration filei +# -------------------------------------------------- +# + +bus "i2c-7" "i2c-2-mux" +chip "tmp421-i2c-7-1E" + label temp1 "ts1" + set temp1_max 50 + set temp1_max_hyst 25 + label temp2 "ts4" + set temp2_max 50 + set temp2_max_hyst 25 + +chip "tmp75-i2c-7-4E" + label temp1 "ts3" + set temp1_max 50 + set temp1_max_hyst 25 + +chip "tmp421-i2c-7-4F" + label temp1 "ts2" + set temp1_max 50 + set temp1_max_hyst 25 + label temp2 "ts5" + set temp2_max 50 + set temp2_max_hyst 25 + +bus "i2c-5" "i2c-2-mux" +chip "wnc_cpld3-i2c-5-33" + label fan1 "fan1" + label fan2 "fan2" + label fan3 "fan3" + label fan4 "fan4" + label fan5 "fan5" diff --git a/platform/barefoot/bfn-platform.mk b/platform/barefoot/bfn-platform.mk index b50a7d51c0f6..b5c67a3fd3a8 100644 --- a/platform/barefoot/bfn-platform.mk +++ b/platform/barefoot/bfn-platform.mk @@ -1,5 +1,5 @@ BFN_PLATFORM = bfnplatform_1.0.0_amd64.deb -$(BFN_PLATFORM)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/rel_7_0/bfnplatform_1.0.0_amd64.deb" +$(BFN_PLATFORM)_URL = "https://github.com/YaoTien/download/blob/master/sonic/sde/7_0_0_18/bfnplatform_1.0.0_amd64.deb" SONIC_ONLINE_DEBS += $(BFN_PLATFORM) # $(BFN_SAI_DEV) $(BFN_SAI_DEV)_DEPENDS += $(BFN_PLATFORM) diff --git a/platform/barefoot/bfn-sai.mk b/platform/barefoot/bfn-sai.mk index a23efaa44a19..28abac7e9093 100644 --- a/platform/barefoot/bfn-sai.mk +++ b/platform/barefoot/bfn-sai.mk @@ -1,5 +1,5 @@ BFN_SAI = bfnsdk_1.0.0_amd64.deb -$(BFN_SAI)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/rel_7_0/bfnsdk_1.0.0_amd64.deb" +$(BFN_SAI)_URL = "https://github.com/YaoTien/download/blob/master/sonic/sde/7_0_0_18/bfnsdk_1.0.0_amd64.deb" # $(BFN_SAI_DEV)_URL = "https://www.dropbox.com/s/4ljk6hzw82rudsr/bfnsdk_1.0.0_amd64.deb?dl=0" SONIC_ONLINE_DEBS += $(BFN_SAI) # $(BFN_SAI_DEV) diff --git a/platform/barefoot/one-image.mk b/platform/barefoot/one-image.mk index c7072d9b4492..b6dc08aa9671 100644 --- a/platform/barefoot/one-image.mk +++ b/platform/barefoot/one-image.mk @@ -3,7 +3,8 @@ SONIC_ONE_IMAGE = sonic-barefoot.bin $(SONIC_ONE_IMAGE)_MACHINE = barefoot $(SONIC_ONE_IMAGE)_IMAGE_TYPE = onie -$(SONIC_ONE_IMAGE)_INSTALLS += $(BFN_PLATFORM_MODULE) -$(SONIC_ONE_IMAGE)_INSTALLS += $(BFN_MONTARA_PLATFORM_MODULE) +#$(SONIC_ONE_IMAGE)_INSTALLS += $(BFN_PLATFORM_MODULE) +#$(SONIC_ONE_IMAGE)_INSTALLS += $(BFN_MONTARA_PLATFORM_MODULE) +$(SONIC_ONE_IMAGE)_INSTALLS += $(WNC_OSW1800_PLATFORM_MODULE) $(SONIC_ONE_IMAGE)_DOCKERS += $(SONIC_INSTALL_DOCKER_IMAGES) SONIC_INSTALLERS += $(SONIC_ONE_IMAGE) diff --git a/platform/barefoot/platform-modules-wnc-osw1800.mk b/platform/barefoot/platform-modules-wnc-osw1800.mk new file mode 100644 index 000000000000..a85ba6b19326 --- /dev/null +++ b/platform/barefoot/platform-modules-wnc-osw1800.mk @@ -0,0 +1,11 @@ +# BFN Platform modules + +WNC_OSW1800_PLATFORM_MODULE_VERSION = 1.0 + +export WNC_OSW1800_PLATFORM_MODULE_VERSION + +WNC_OSW1800_PLATFORM_MODULE = platform-modules-wnc-osw1800_$(WNC_OSW1800_PLATFORM_MODULE_VERSION)_amd64.deb +$(WNC_OSW1800_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-wnc-osw1800 +$(WNC_OSW1800_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) +$(WNC_OSW1800_PLATFORM_MODULE)_PLATFORM = x86_64-wnc_osw1800-r0 +SONIC_DPKG_DEBS += $(WNC_OSW1800_PLATFORM_MODULE) diff --git a/platform/barefoot/rules.mk b/platform/barefoot/rules.mk index ab9a1679af53..c339b81699c1 100644 --- a/platform/barefoot/rules.mk +++ b/platform/barefoot/rules.mk @@ -1,5 +1,6 @@ include $(PLATFORM_PATH)/platform-modules-bfn.mk include $(PLATFORM_PATH)/platform-modules-bfn-montara.mk +include $(PLATFORM_PATH)/platform-modules-wnc-osw1800.mk include $(PLATFORM_PATH)/bfn-sai.mk include $(PLATFORM_PATH)/docker-syncd-bfn.mk include $(PLATFORM_PATH)/docker-syncd-bfn-rpc.mk diff --git a/platform/barefoot/sonic-platform-modules-wnc-osw1800/LICENSE b/platform/barefoot/sonic-platform-modules-wnc-osw1800/LICENSE new file mode 100644 index 000000000000..676cdeec726b --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-wnc-osw1800/LICENSE @@ -0,0 +1,15 @@ +Copyright (C) 2016 Microsoft, 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 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/barefoot/sonic-platform-modules-wnc-osw1800/MAINTAINERS b/platform/barefoot/sonic-platform-modules-wnc-osw1800/MAINTAINERS new file mode 100644 index 000000000000..a578b60e24de --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-wnc-osw1800/MAINTAINERS @@ -0,0 +1,7 @@ +# This file describes the maintainers for sonic-platform-modules-wnc-osw1800 +# See the SONiC project governance document for more information + +Name = "WNC" +Email = "wnc@wnc.com.tw" +Github = barefootnetworks +Mailinglist = wnc@wnc.com.tw diff --git a/platform/barefoot/sonic-platform-modules-wnc-osw1800/README.md b/platform/barefoot/sonic-platform-modules-wnc-osw1800/README.md new file mode 100644 index 000000000000..707c1068d6e6 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-wnc-osw1800/README.md @@ -0,0 +1,2 @@ +# sonic-platform-modules-wnc-osw1800 +Device drivers for support of BFN platform for the SONiC project diff --git a/platform/barefoot/sonic-platform-modules-wnc-osw1800/debian/changelog b/platform/barefoot/sonic-platform-modules-wnc-osw1800/debian/changelog new file mode 100644 index 000000000000..466378b892d1 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-wnc-osw1800/debian/changelog @@ -0,0 +1,5 @@ +platform-modules-wnc-osw1800 (1.0) unstable; urgency=low + + * Initial release + + -- WNC Mon, 11 Nov 2015 11:11:11 -0800 diff --git a/platform/barefoot/sonic-platform-modules-wnc-osw1800/debian/compat b/platform/barefoot/sonic-platform-modules-wnc-osw1800/debian/compat new file mode 100644 index 000000000000..45a4fb75db86 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-wnc-osw1800/debian/compat @@ -0,0 +1 @@ +8 diff --git a/platform/barefoot/sonic-platform-modules-wnc-osw1800/debian/control b/platform/barefoot/sonic-platform-modules-wnc-osw1800/debian/control new file mode 100644 index 000000000000..0659d35786db --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-wnc-osw1800/debian/control @@ -0,0 +1,12 @@ +Source: platform-modules-wnc-osw1800 +Section: main +Priority: extra +Maintainer: WNC +Build-Depends: debhelper (>= 8.0.0), bzip2 +Standards-Version: 3.9.3 + +Package: platform-modules-wnc-osw1800 +Architecture: amd64 +Depends: linux-image-3.16.0-4-amd64 +Description: kernel modules for platform devices such as fan, led, sfp + diff --git a/platform/barefoot/sonic-platform-modules-wnc-osw1800/debian/copyright b/platform/barefoot/sonic-platform-modules-wnc-osw1800/debian/copyright new file mode 100644 index 000000000000..ade42b7aa75a --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-wnc-osw1800/debian/copyright @@ -0,0 +1,15 @@ +Provides linux kernel driver for BF PCIe devices + +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/barefoot/sonic-platform-modules-wnc-osw1800/debian/files b/platform/barefoot/sonic-platform-modules-wnc-osw1800/debian/files new file mode 100644 index 000000000000..6ec8776133dc --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-wnc-osw1800/debian/files @@ -0,0 +1 @@ +platform-modules-wnc-osw1800_1.0_amd64.deb main extra diff --git a/platform/barefoot/sonic-platform-modules-wnc-osw1800/debian/rules b/platform/barefoot/sonic-platform-modules-wnc-osw1800/debian/rules new file mode 100755 index 000000000000..644ab1ade433 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-wnc-osw1800/debian/rules @@ -0,0 +1,38 @@ +#!/usr/bin/make -f + +export INSTALL_MOD_DIR:=extra + +PACKAGE_NAME := platform-modules-wnc-osw1800 +KVERSION ?= $(shell uname -r) +KERNEL_SRC := /lib/modules/$(KVERSION) +MODULE_SRC := $(shell pwd)/modules +SCRIPT_SRC := $(shell pwd)/scripts +SERVICE_SRC := $(shell pwd)/service + +%: + dh $@ + +override_dh_auto_build: + make -C $(KERNEL_SRC)/build M=$(MODULE_SRC) + +override_dh_auto_install: + dh_installdirs -p$(PACKAGE_NAME) $(KERNEL_SRC)/$(INSTALL_MOD_DIR) + cp $(MODULE_SRC)/*.ko debian/$(PACKAGE_NAME)/$(KERNEL_SRC)/$(INSTALL_MOD_DIR) + dh_installdirs -p$(PACKAGE_NAME) usr/local/bin + cp -r $(SCRIPT_SRC)/* debian/$(PACKAGE_NAME)/usr/local/bin + dh_installdirs -p$(PACKAGE_NAME) /etc/systemd/system + cp -r $(SERVICE_SRC)/* debian/$(PACKAGE_NAME)/etc/systemd/system + dh_installdirs -p$(PACKAGE_NAME) /etc/systemd/system/multi-user.target.wants + ln -s ../device_node.service debian/$(PACKAGE_NAME)/etc/systemd/system/multi-user.target.wants/device_node.service + ln -s ../driver_load.service debian/$(PACKAGE_NAME)/etc/systemd/system/multi-user.target.wants/driver_load.service + +override_dh_usrlocal: + +override_dh_pysupport: + +override_dh_clean: + dh_clean + rm -f $(MODULE_SRC)/*.o $(MODULE_SRC)/*.ko $(MODULE_SRC)/*.mod.c $(MODULE_SRC)/.*.cmd + rm -f $(MODULE_SRC)/Module.markers $(MODULE_SRC)/Module.symvers $(MODULE_SRC)/modules.order + rm -rf $(MODULE_SRC)/.tmp_versions + diff --git a/platform/barefoot/sonic-platform-modules-wnc-osw1800/modules/Makefile b/platform/barefoot/sonic-platform-modules-wnc-osw1800/modules/Makefile new file mode 100644 index 000000000000..29b904dd3232 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-wnc-osw1800/modules/Makefile @@ -0,0 +1,6 @@ +obj-m := bf_kdrv.o +obj-m += bf_tun.o +obj-m += i2c-mcp2221.o +obj-m += wnc_cpld.o +obj-m += wnc_cpld3.o +obj-m += wnc_eeprom.o diff --git a/platform/barefoot/sonic-platform-modules-wnc-osw1800/modules/bf_kdrv.c b/platform/barefoot/sonic-platform-modules-wnc-osw1800/modules/bf_kdrv.c new file mode 100644 index 000000000000..5f084f6a040f --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-wnc-osw1800/modules/bf_kdrv.c @@ -0,0 +1,1249 @@ +/******************************************************************************* + * BAREFOOT NETWORKS CONFIDENTIAL & PROPRIETARY + * + * Copyright (c) 2015-2016 Barefoot Networks, Inc. + + * All Rights Reserved. + * + * NOTICE: All information contained herein is, and remains the property of + * Barefoot Networks, Inc. and its suppliers, if any. The intellectual and + * technical concepts contained herein are proprietary to Barefoot Networks, + * Inc. + * and its suppliers and may be covered by U.S. and Foreign Patents, patents in + * process, and are protected by trade secret or copyright law. + * Dissemination of this information or reproduction of this material is + * strictly forbidden unless prior written permission is obtained from + * Barefoot Networks, Inc. + * + * No warranty, explicit or implicit is provided, unless granted under a + * written agreement with Barefoot Networks, Inc. + * + * $Id: $ + * + ******************************************************************************/ +/** + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2015 Barefoot Networks. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * 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... + * + **/ + +/* bf_drv kernel module + * + * This is kernel mode driver for Tofino chip. + * Provides user space mmap service and user space "wait for interrupt" + * and "enable interrupt" services. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 16, 0) +//#error unsupported linux kernel version +#endif + +/* TBD: Need to build with CONFIG_PCI_MSI */ +extern int pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec); +extern int pci_enable_msix_range(struct pci_dev *dev, struct msix_entry *entries, int minvec, int maxvec); + +#define PCI_VENDOR_ID_BF 0x1d1c +#define TOFINO_DEV_ID_A0 0x01 +#define TOFINO_DEV_ID_B0 0x10 + +#ifndef PCI_MSIX_ENTRY_SIZE +#define PCI_MSIX_ENTRY_SIZE 16 +#define PCI_MSIX_ENTRY_LOWER_ADDR 0 +#define PCI_MSIX_ENTRY_UPPER_ADDR 4 +#define PCI_MSIX_ENTRY_DATA 8 +#define PCI_MSIX_ENTRY_VECTOR_CTRL 12 +#define PCI_MSIX_ENTRY_CTRL_MASKBIT 1 +#endif + +#define BF_CLASS_NAME "bf" +#define BF_MAX_DEVICE_CNT 256 +#define BF_INTR_MODE_NONE_NAME "none" +#define BF_INTR_MODE_LEGACY_NAME "legacy" +#define BF_INTR_MODE_MSI_NAME "msi" +#define BF_INTR_MODE_MSIX_NAME "msix" +#define BF_MAX_BAR_MAPS 6 +#define BF_MSIX_ENTRY_CNT 128 /* TBD make it 512 */ +#define BF_MSI_ENTRY_CNT 2 + +/* interrupt mode */ +enum bf_intr_mode { + BF_INTR_MODE_NONE = 0, + BF_INTR_MODE_LEGACY, + BF_INTR_MODE_MSI, + BF_INTR_MODE_MSIX +}; + +/* device memory */ +struct bf_dev_mem { + const char *name; + phys_addr_t addr; + resource_size_t size; + void __iomem *internal_addr; +}; + +struct bf_listener { + struct bf_pci_dev *bfdev; + s32 event_count[BF_MSIX_ENTRY_CNT]; + int minor; + struct bf_listener *next; +}; + +/* device information */ +struct bf_dev_info { + struct module *owner; + struct device *dev; + int minor; + atomic_t event[BF_MSIX_ENTRY_CNT]; + wait_queue_head_t wait; + const char *version; + struct bf_dev_mem mem[BF_MAX_BAR_MAPS]; + struct msix_entry *msix_entries; + long irq; /* first irq vector */ + int num_irq; /* number of irq vectors */ + unsigned long irq_flags;/* sharable ?? */ + int pci_error_state; /* was there a pci bus error */ +}; + +/* cookie to be passed to IRQ handler, useful especially with MSIX */ +struct bf_int_vector { + struct bf_pci_dev *bf_dev; + int int_vec_offset; +}; + + +/** + * A structure describing the private information for a BF pcie device. + */ +struct bf_pci_dev { + struct bf_dev_info info; + struct pci_dev *pdev; + enum bf_intr_mode mode; + u8 instance; + char name[16]; + struct bf_int_vector bf_int_vec[BF_MSIX_ENTRY_CNT]; + struct bf_listener *listener_head; /* head of a singly linked list of + listeners */ +}; + +/* Keep any global information here that must survive even after the + * bf_pci_dev is free-ed up. + */ +struct bf_global { + struct bf_pci_dev *bfdev ; + struct cdev *bf_cdev; + struct fasync_struct *async_queue; +}; + +static int bf_major; +static int bf_minor[BF_MAX_DEVICE_CNT] = {0}; +static struct class *bf_class = NULL; +static char *intr_mode = NULL; +static enum bf_intr_mode bf_intr_mode_default = BF_INTR_MODE_MSI; +static spinlock_t bf_nonisr_lock; +/* dev->minor should index into this array */ +static struct bf_global bf_global[BF_MAX_DEVICE_CNT]; + +static void bf_add_listener(struct bf_pci_dev *bfdev, + struct bf_listener *listener) +{ + struct bf_listener **cur_listener = &bfdev->listener_head; + + if (!listener) { + return; + } + spin_lock(&bf_nonisr_lock); + + while (*cur_listener) { + cur_listener = &((*cur_listener)->next); + } + *cur_listener = listener; + listener->next = NULL; + + spin_unlock(&bf_nonisr_lock); +} + +static void bf_remove_listener(struct bf_pci_dev *bfdev, + struct bf_listener *listener) +{ + struct bf_listener **cur_listener = &bfdev->listener_head; + + /* in case of certain error conditions, this function might be called after bf_pci_remove() + */ + if (!bfdev || !listener) { + return; + } + spin_lock(&bf_nonisr_lock); + + if (*cur_listener == listener) { + *cur_listener = listener->next; + } else { + while (*cur_listener) { + if ((*cur_listener)->next == listener) { + (*cur_listener)->next = listener->next; + break; + } + cur_listener = &((*cur_listener)->next); + } + listener->next = NULL; + } + + spin_unlock(&bf_nonisr_lock); +} + +/* a pool of minor numbers is maintained */ +/* return the first available minor number */ +static int bf_get_next_minor_no(int *minor) +{ + int i; + + spin_lock(&bf_nonisr_lock); + for(i = 0; i < BF_MAX_DEVICE_CNT; i++) { + if (bf_minor[i] == 0) { + *minor = i; + bf_minor[i] = 1; /* mark it as taken */ + spin_unlock(&bf_nonisr_lock); + return 0; + } + } + *minor = -1; + spin_unlock(&bf_nonisr_lock); + return -1; +} + +/* return a minor number back to the pool for recycling */ +static int bf_return_minor_no(int minor) +{ + int err; + + spin_lock(&bf_nonisr_lock); + if (bf_minor[minor] == 0) { /* was already returned */ + err = -1; /* don't change anything, but return error */ + } else { + bf_minor[minor] = 0; /* mark it as available */ + err = 0; + } + spin_unlock(&bf_nonisr_lock); + return err; +} + +static inline struct bf_pci_dev *bf_get_pci_dev(struct bf_dev_info *info) +{ + return container_of(info, struct bf_pci_dev, info); +} + +/* + * It masks the msix on/off of generating MSI-X messages. + */ +static void +bf_msix_mask_irq(struct msi_desc *desc, int32_t state) +{ + u32 mask_bits = desc->masked; + unsigned offset = desc->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE + + PCI_MSIX_ENTRY_VECTOR_CTRL; + + if (state != 0) + mask_bits &= ~PCI_MSIX_ENTRY_CTRL_MASKBIT; + else + mask_bits |= PCI_MSIX_ENTRY_CTRL_MASKBIT; + + if (mask_bits != desc->masked) { + writel(mask_bits, desc->mask_base + offset); + readl(desc->mask_base); + desc->masked = mask_bits; + } +} + +/** + * irqcontrol can be used to disable/enable interrupt from user space processes. + * + * @param bf_dev + * pointer to bf_pci_dev + * @param irq_state + * state value. 1 to enable interrupt, 0 to disable interrupt. + * + * @return + * - On success, 0. + * - On failure, a negative value. + */ +static int +bf_pci_irqcontrol(struct bf_pci_dev *bfdev, s32 irq_state) +{ + struct pci_dev *pdev = bfdev->pdev; + + pci_cfg_access_lock(pdev); + if (bfdev->mode == BF_INTR_MODE_LEGACY) + pci_intx(pdev, !!irq_state); + + else if (bfdev->mode == BF_INTR_MODE_MSIX) { + struct msi_desc *desc; +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,2,0) + list_for_each_entry(desc, &pdev->msi_list, list) + bf_msix_mask_irq(desc, irq_state); +#else + for_each_pci_msi_entry(desc, pdev) + bf_msix_mask_irq(desc, irq_state); +#endif + } + pci_cfg_access_unlock(pdev); + + return 0; +} + +/** + * interrupt handler which will check if the interrupt is from the right + * device. If so, disable it here and will be enabled later. + */ +static irqreturn_t bf_pci_irqhandler(int irq, struct bf_pci_dev *bfdev) +{ + /* Legacy mode need to mask in hardware */ + if (bfdev->mode == BF_INTR_MODE_LEGACY && + !pci_check_and_mask_intx(bfdev->pdev)) + return IRQ_NONE; + + /* NOTE : if bfdev->info.pci_error_state == 1, then do not access the + * device and return IRQ_NOTHANDLED. + */ + /* Message signal mode, no share IRQ and automasked */ + return IRQ_HANDLED; +} + +/* Remap pci resources described by bar #pci_bar */ +static int +bf_pci_setup_iomem(struct pci_dev *dev, struct bf_dev_info *info, + int n, int pci_bar, const char *name) +{ + unsigned long addr, len; + void *internal_addr; + + if (sizeof(info->mem) / sizeof(info->mem[0]) <= n) + return -EINVAL; + + addr = pci_resource_start(dev, pci_bar); + len = pci_resource_len(dev, pci_bar); + if (addr == 0 || len == 0) + return -1; + internal_addr = pci_ioremap_bar(dev, pci_bar); + if (internal_addr == NULL) + return -1; + info->mem[n].name = name; + info->mem[n].addr = addr; + info->mem[n].internal_addr = internal_addr; + info->mem[n].size = len; + return 0; +} + +/* Unmap previously ioremap'd resources */ +static void +bf_pci_release_iomem(struct bf_dev_info *info) +{ + int i; + + for (i = 0; i < BF_MAX_BAR_MAPS; i++) { + if (info->mem[i].internal_addr) + iounmap(info->mem[i].internal_addr); + } +} + +static int +bf_setup_bars(struct pci_dev *dev, struct bf_dev_info *info) +{ + int i, iom, ret; + unsigned long flags; + static const char *bar_names[BF_MAX_BAR_MAPS] = { + "BAR0", "BAR1", "BAR2", "BAR3", "BAR4", "BAR5", + }; + + iom = 0; + + for (i = 0; i < BF_MAX_BAR_MAPS; i++) { + if (pci_resource_len(dev, i) != 0 && + pci_resource_start(dev, i) != 0) { + flags = pci_resource_flags(dev, i); + if (flags & IORESOURCE_MEM) { + ret = bf_pci_setup_iomem(dev, info, iom, i, bar_names[i]); + if (ret != 0) + return ret; + iom++; + } + } + } + return (iom != 0) ? ret : -ENOENT; +} + +static irqreturn_t bf_interrupt(int irq, void *bfdev_id) +{ + struct bf_pci_dev *bfdev = ((struct bf_int_vector *)bfdev_id)->bf_dev; + int vect_off = ((struct bf_int_vector *)bfdev_id)->int_vec_offset; + + irqreturn_t ret = bf_pci_irqhandler(irq, bfdev); + + if (ret == IRQ_HANDLED) + atomic_inc(&(bfdev->info.event[vect_off])); + + return ret; +} + +static unsigned int bf_poll(struct file *filep, poll_table *wait) +{ + struct bf_listener *listener = (struct bf_listener *)filep->private_data; + struct bf_pci_dev *bfdev = listener->bfdev; + int i; + + if (!bfdev) { + return -ENODEV; + } + if (!bfdev->info.irq) + return -EIO; + + poll_wait(filep, &bfdev->info.wait, wait); + + for (i = 0; i < BF_MSIX_ENTRY_CNT; i++) + if (listener->event_count[i] != atomic_read(&bfdev->info.event[i])) + return POLLIN | POLLRDNORM; + return 0; +} + +static int bf_find_mem_index(struct vm_area_struct *vma) +{ + struct bf_pci_dev *bfdev = vma->vm_private_data; + if (vma->vm_pgoff < BF_MAX_BAR_MAPS) { + if (bfdev->info.mem[vma->vm_pgoff].size == 0) + return -1; + return (int)vma->vm_pgoff; + } + return -1; +} + +static const struct vm_operations_struct bf_physical_vm_ops = { +#ifdef CONFIG_HAVE_IOREMAP_PROT + .access = generic_access_phys, +#endif +}; + +static int bf_mmap_physical(struct vm_area_struct *vma) +{ + struct bf_pci_dev *bfdev = vma->vm_private_data; + int bar = bf_find_mem_index(vma); + struct bf_dev_mem *mem; + if (bar < 0) + return -EINVAL; + + mem = bfdev->info.mem + bar; + + if (mem->addr & ~PAGE_MASK) + return -ENODEV; + if (vma->vm_end - vma->vm_start > mem->size) + return -EINVAL; + + vma->vm_ops = &bf_physical_vm_ops; + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + + /* + * We cannot use the vm_iomap_memory() helper here, + * because vma->vm_pgoff is the map index we looked + * up above in bf_find_mem_index(), rather than an + * actual page offset into the mmap. + * + * So we just do the physical mmap without a page + * offset. + */ + return remap_pfn_range(vma, vma->vm_start, mem->addr >> PAGE_SHIFT, + vma->vm_end - vma->vm_start, vma->vm_page_prot); +} + +static int bf_mmap(struct file *filep, struct vm_area_struct *vma) +{ + struct bf_listener *listener = filep->private_data; + struct bf_pci_dev *bfdev = listener->bfdev; + int bar; + unsigned long requested_pages, actual_pages; + + if (!bfdev) { + return -ENODEV; + } + if (vma->vm_end < vma->vm_start) + return -EINVAL; + + vma->vm_private_data = bfdev; + + bar = bf_find_mem_index(vma); + if (bar < 0) + return -EINVAL; + + requested_pages = vma_pages(vma); + actual_pages = ((bfdev->info.mem[bar].addr & ~PAGE_MASK) + + bfdev->info.mem[bar].size + PAGE_SIZE -1) >> PAGE_SHIFT; + if (requested_pages > actual_pages) + return -EINVAL; + + return bf_mmap_physical(vma); +} + +static int bf_fasync(int fd, struct file *filep, int mode) +{ + int minor; + + if (!filep->private_data) { + return (-EINVAL); + } + minor = ((struct bf_listener *)filep->private_data)->minor; + if (minor >= BF_MAX_DEVICE_CNT) { + return (-EINVAL); + } + if (mode == 0 && &bf_global[minor].async_queue == NULL) { + return 0; /* nothing to do */ + } + return (fasync_helper(fd, filep, mode, &bf_global[minor].async_queue)); +} + +static int bf_open(struct inode *inode, struct file *filep) +{ + struct bf_pci_dev *bfdev; + struct bf_listener *listener; + int i; + + bfdev = bf_global[iminor(inode)].bfdev; + listener = kmalloc(sizeof(*listener), GFP_KERNEL); + if (listener) { + listener->bfdev = bfdev; + listener->minor = bfdev->info.minor; + listener->next = NULL; + bf_add_listener(bfdev, listener); + for (i = 0; i < BF_MSIX_ENTRY_CNT; i++) + listener->event_count[i] = atomic_read(&bfdev->info.event[i]); + filep->private_data = listener; + return 0; + } else { + return(-ENOMEM); + } +} + +static int bf_release(struct inode *inode, struct file *filep) +{ + struct bf_listener *listener = filep->private_data; + + bf_fasync(-1, filep, 0); /* empty any process id in the notification list */ + if (listener->bfdev) { + bf_remove_listener(listener->bfdev, listener); + } + kfree(listener); + return 0; +} + +/* user space support: make read() system call after poll() of select() */ +static ssize_t bf_read(struct file *filep, char __user *buf, + size_t count, loff_t *ppos) +{ + struct bf_listener *listener = filep->private_data; + struct bf_pci_dev *bfdev = listener->bfdev; + int retval, event_count[BF_MSIX_ENTRY_CNT]; + int i, mismatch_found = 0; /* OR of per vector mismatch */ + unsigned char cnt_match[BF_MSIX_ENTRY_CNT]; /* per vector mismatch */ + + if (!bfdev) { + return -ENODEV; + } + /* irq must be setup for read() to work */ + if (!bfdev->info.irq) + return -EIO; + + /* ensure that there is enough space on user buffer for the given interrupt + * mode */ + if (bfdev->mode == BF_INTR_MODE_MSIX) { + if (count < sizeof(s32)*BF_MSIX_ENTRY_CNT) + return -EINVAL; + count = sizeof(s32)*BF_MSIX_ENTRY_CNT; + } else if (bfdev->mode == BF_INTR_MODE_MSI) { + if (count < sizeof(s32)*BF_MSI_ENTRY_CNT) + return -EINVAL; + count = sizeof(s32)*BF_MSI_ENTRY_CNT; + } else { + if (count < sizeof(s32)) + return -EINVAL; + count = sizeof(s32); + } + count = sizeof(s32)*BF_MSIX_ENTRY_CNT; + + do { + set_current_state(TASK_INTERRUPTIBLE); + + for (i = 0; i < (count/sizeof(s32)); i++) { + event_count[i] = atomic_read(&(bfdev->info.event[i])); + if (event_count[i] != listener->event_count[i]) { + mismatch_found |= 1; + cnt_match[i] = 1; + } else { + event_count[i] = 0; + cnt_match[i] = 0; + } + } + if (mismatch_found) { + __set_current_state(TASK_RUNNING); + if (copy_to_user(buf, &event_count, count)) + retval = -EFAULT; + else { /* adjust the listener->event_count; */ + for (i = 0 ; i < BF_MSIX_ENTRY_CNT; i++) { + if (cnt_match[i]) { + listener->event_count[i] = event_count[i]; + } + } + retval = count; + } + break; + } + + if (filep->f_flags & O_NONBLOCK) { + retval = -EAGAIN; + break; + } + + if (signal_pending(current)) { + retval = -ERESTARTSYS; + break; + } + schedule(); + } while (1); + + __set_current_state(TASK_RUNNING); + + return retval; +} + +/* user space is supposed to call this after it is done with interrupt + * processing + */ +static ssize_t bf_write(struct file *filep, const char __user *buf, + size_t count, loff_t *ppos) +{ + struct bf_listener *listener = filep->private_data; + struct bf_pci_dev *bfdev = listener->bfdev; + ssize_t ret; + s32 int_en; + + if (!bfdev || !bfdev->info.irq) + return -EIO; + + if (count != sizeof(s32)) + return -EINVAL; + + if (copy_from_user(&int_en, buf, count)) + return -EFAULT; + + /* clear pci_error_state */ + bfdev->info.pci_error_state = 0; + + ret = bf_pci_irqcontrol(bfdev, int_en); + + return ret ? ret : sizeof(s32); +} + +static const struct file_operations bf_fops = { + .owner = THIS_MODULE, + .open = bf_open, + .release = bf_release, + .read = bf_read, + .write = bf_write, + .mmap = bf_mmap, + .poll = bf_poll, + .fasync = bf_fasync, +}; + +static int bf_major_init(struct bf_pci_dev *bfdev, int minor) +{ + struct cdev *cdev; + static const char name[] = "bf"; + dev_t bf_dev = 0; + int result; + + result = alloc_chrdev_region(&bf_dev, 0, BF_MAX_DEVICE_CNT, name); + if (result) + return result; + + result = -ENOMEM; + cdev = cdev_alloc(); + if (!cdev) { + goto fail_dev_add; + } + cdev->ops = &bf_fops; + cdev->owner = THIS_MODULE; + kobject_set_name(&cdev->kobj, "%s", name); + result = cdev_add(cdev, bf_dev, BF_MAX_DEVICE_CNT); + + if (result) + goto fail_dev_add; + + bf_major = MAJOR(bf_dev); + bf_global[minor].bf_cdev = cdev; + return 0; + +fail_dev_add: + unregister_chrdev_region(bf_dev, BF_MAX_DEVICE_CNT); + return result; +} + +static void bf_major_cleanup(struct bf_pci_dev *bfdev, int minor) +{ + unregister_chrdev_region(MKDEV(bf_major, 0), BF_MAX_DEVICE_CNT); + cdev_del(bf_global[minor].bf_cdev); +} + +static int bf_init_cdev(struct bf_pci_dev *bfdev, int minor) +{ + int ret; + ret = bf_major_init(bfdev, minor); + if (ret) + return ret; + + bf_class = class_create(THIS_MODULE, BF_CLASS_NAME); + if (!bf_class) { + printk(KERN_ERR "create_class failed for bf_dev\n"); + ret = -ENODEV; + goto err_class_register; + } + return 0; + +err_class_register: + bf_major_cleanup(bfdev, minor); + return ret; +} + +static void bf_remove_cdev(struct bf_pci_dev *bfdev) +{ + class_destroy(bf_class); + bf_major_cleanup(bfdev, bfdev->info.minor); +} + + +/** + * bf_register_device - register a new userspace mem device + * @parent: parent device + * @bfdev: bf pci device + * + * returns zero on success or a negative error code. + */ +int bf_register_device(struct device *parent, struct bf_pci_dev *bfdev) +{ + struct bf_dev_info *info = &bfdev->info; + int i, j, ret = 0; + int minor; + + if (!parent || !info || !info->version) + return -EINVAL; + + init_waitqueue_head(&info->wait); + + for (i = 0; i < BF_MSIX_ENTRY_CNT; i++) { + atomic_set(&info->event[i], 0); + } + + if (bf_get_next_minor_no(&minor)) { + return -EINVAL; + } + + ret = bf_init_cdev(bfdev, minor); + if (ret) { + printk(KERN_ERR "BF: device cdev creation failed\n"); + return ret; + } + + info->dev = device_create(bf_class, parent, + MKDEV(bf_major, minor), bfdev, + "bf%d", minor); + if (!info->dev) { + printk(KERN_ERR "BF: device creation failed\n"); + return -ENODEV; + } + + info->minor = minor; + + /* bind ISRs and request interrupts */ + if (info->irq && (bfdev->mode != BF_INTR_MODE_NONE)) { + /* + * Note that we deliberately don't use devm_request_irq + * here. The parent module can unregister the UIO device + * and call pci_disable_msi, which requires that this + * irq has been freed. However, the device may have open + * FDs at the time of unregister and therefore may not be + * freed until they are released. + */ + if (bfdev->mode == BF_INTR_MODE_LEGACY) { + ret = request_irq(info->irq, bf_interrupt, + info->irq_flags, bfdev->name, + (void *)&(bfdev->bf_int_vec[0])); + if (ret) { + printk(KERN_ERR "bf failed to request legacy irq %ld error %d\n", + info->irq, ret); + return ret; + } + printk(KERN_NOTICE "BF allocating legacy int vector %ld\n", info->irq); + } else if (bfdev->mode == BF_INTR_MODE_MSIX) { + for (i = 0; i < info->num_irq; i++) { + ret = request_irq(info->msix_entries[i].vector, bf_interrupt, + info->irq_flags, bfdev->name, + (void *)&(bfdev->bf_int_vec[i])); + if (ret) { + /* undo all other previous bindings */ + printk(KERN_ERR "bf failed to request MSIX ret %d itr %d\n", ret, i); + for (j = i - 1; j >= 0; j--) { + free_irq(info->msix_entries[j].vector, + (void *)&(bfdev->bf_int_vec[j])); + } + return ret; + } + } + printk(KERN_NOTICE "BF allocating %d MSIx vectors from %ld\n", + info->num_irq, info->irq); + } else if (bfdev->mode == BF_INTR_MODE_MSI) { + for (i = 0; i < info->num_irq; i++) { + ret = request_irq(info->irq + i, bf_interrupt, + info->irq_flags, bfdev->name, + (void *)&(bfdev->bf_int_vec[i])); + if (ret) { + /* undo all other previous bindings */ + printk(KERN_ERR "bf failed to request MSI ret %d itr %d\n", ret, i); + for (j = i - 1; j >= 0; j--) { + free_irq(info->irq + j, (void *)&(bfdev->bf_int_vec[j])); + } + return ret; + } + } + printk(KERN_NOTICE "BF allocating %d MSI vectors from %ld\n", + info->num_irq, info->irq); + } + } + return 0; +} + +/** + * bf_unregister_device - register a new userspace mem device + * @bfdev: bf pci device + * + * returns none + */ +void bf_unregister_device(struct bf_pci_dev *bfdev) +{ + struct bf_dev_info *info = &bfdev->info; + int i; + + if (info->irq) { + if (bfdev->mode == BF_INTR_MODE_LEGACY) { + free_irq(info->irq, (void *)&(bfdev->bf_int_vec[0])); + } else if (bfdev->mode == BF_INTR_MODE_MSIX) { + for (i = 0; i < info->num_irq; i++) { + free_irq(info->msix_entries[i].vector, (void *)&(bfdev->bf_int_vec[i])); + } + } else if (bfdev->mode == BF_INTR_MODE_MSI) { + for (i = 0; i < info->num_irq; i++) { + free_irq(info->irq + i, (void *)&(bfdev->bf_int_vec[i])); + } + } + } + device_destroy(bf_class, MKDEV(bf_major, info->minor)); + bf_remove_cdev(bfdev); + bf_return_minor_no(info->minor); + return; +} + +static inline struct device *pci_dev_to_dev(struct pci_dev *pdev) +{ + return &pdev->dev; +} + +static int +bf_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) +{ + struct bf_pci_dev *bfdev; + int err, pci_use_highmem; + int i, num_irq; + + memset(bf_global, 0, sizeof(bf_global)); + + bfdev = kzalloc(sizeof(struct bf_pci_dev), GFP_KERNEL); + if (!bfdev) + return -ENOMEM; + + /* init the cookies to be passed to ISRs */ + for (i = 0; i < BF_MSIX_ENTRY_CNT; i++) { + bfdev->bf_int_vec[i].int_vec_offset = i; + bfdev->bf_int_vec[i].bf_dev = bfdev; + } + + /* initialize intr_mode to none */ + bfdev->mode = BF_INTR_MODE_NONE; + + /* clear pci_error_state */ + bfdev->info.pci_error_state = 0; + + /* + * enable device + */ + err = pci_enable_device(pdev); + if (err != 0) { + dev_err(&pdev->dev, "Cannot enable PCI device\n"); + goto fail_free; + } + + /* + * reserve device's PCI memory regions for use by this + * module + */ + err = pci_request_regions(pdev, "bf_umem"); + if (err != 0) { + dev_err(&pdev->dev, "Cannot request regions\n"); + goto fail_pci_disable; + } + /* remap IO memory */ + err = bf_setup_bars(pdev, &bfdev->info); + if (err != 0) + goto fail_release_iomem; + + if (!dma_set_mask(pci_dev_to_dev(pdev), DMA_BIT_MASK(64)) && + !dma_set_coherent_mask(pci_dev_to_dev(pdev), DMA_BIT_MASK(64))) { + pci_use_highmem = 1; + } else { + err = dma_set_mask(pci_dev_to_dev(pdev), DMA_BIT_MASK(32)); + if (err) { + err = dma_set_coherent_mask(pci_dev_to_dev(pdev), + DMA_BIT_MASK(32)); + if (err) { + dev_err(pci_dev_to_dev(pdev), "No usable DMA " + "configuration, aborting\n"); + goto fail_release_iomem; + } + } + pci_use_highmem = 0; + } + + /* enable pci error reporting */ + /* for the current kernel version, kernel config must have set the followings: + * CONFIG_PCIEPORTBUS=y and CONFIG_PCIEAER = y + * we have pci_error_handlers defined that gets invoked by kernel AER module + * upon detecting the pcie error on this device's addresses. + * However, there seems no way that AER would pass the offending addresses + * to the callback functions. AER logs the error messages on the console. + * This driver's calback function send the SIGIO signal to the user space + * to indicate the error condition. + */ + pci_enable_pcie_error_reporting(pdev); + + /* enable bus mastering on the device */ + pci_set_master(pdev); + + /* fill in bfdev info */ + bfdev->info.version = "0.2"; + bfdev->info.owner = THIS_MODULE; + bfdev->pdev = pdev; + + switch (bf_intr_mode_default) { +#ifdef CONFIG_PCI_MSI + case BF_INTR_MODE_MSIX: + /* Only 1 msi-x vector needed */ + bfdev->info.msix_entries = kcalloc(BF_MSIX_ENTRY_CNT, + sizeof(struct msix_entry), GFP_KERNEL); + if (!bfdev->info.msix_entries) { + err = -ENOMEM; + goto fail_clear_pci_master; + } + for (i = 0; i < BF_MSIX_ENTRY_CNT; i++) { + bfdev->info.msix_entries[i].entry= i; + } + num_irq = pci_enable_msix_range(pdev, bfdev->info.msix_entries, + BF_MSIX_ENTRY_CNT, BF_MSIX_ENTRY_CNT); + if (num_irq == BF_MSIX_ENTRY_CNT) { + dev_dbg(&pdev->dev, "using MSI-X"); + bfdev->info.num_irq = num_irq; + bfdev->info.irq = bfdev->info.msix_entries[0].vector; + bfdev->mode = BF_INTR_MODE_MSIX; + printk(KERN_DEBUG "bf using %d MSIX irq from %ld\n", num_irq, + bfdev->info.irq); + break; + } else { + if (num_irq) + pci_disable_msix(pdev); + kfree(bfdev->info.msix_entries); + bfdev->info.msix_entries = NULL; + printk(KERN_ERR "bf error allocating MSIX vectors. Trying MSI...\n"); + /* and, fall back to MSI */ + } + /* ** intentional no-break */ + case BF_INTR_MODE_MSI: + num_irq = pci_enable_msi_range(pdev, BF_MSI_ENTRY_CNT, BF_MSI_ENTRY_CNT); + if (num_irq > 0) { + dev_dbg(&pdev->dev, "using MSI"); + bfdev->info.num_irq = num_irq; + bfdev->info.irq = pdev->irq; + bfdev->mode = BF_INTR_MODE_MSI; + printk(KERN_DEBUG "bf using %d MSI irq from %ld\n", bfdev->info.num_irq, + bfdev->info.irq); + break; + } +#endif /* CONFIG_PCI_MSI */ + /* fall back to Legacy Interrupt, intentional no-break */ + + case BF_INTR_MODE_LEGACY: + if (pci_intx_mask_supported(pdev)) { + dev_dbg(&pdev->dev, "using INTX"); + bfdev->info.irq_flags = IRQF_SHARED; + bfdev->info.irq = pdev->irq; + bfdev->mode = BF_INTR_MODE_LEGACY; + printk(KERN_DEBUG "bf using LEGACY irq %ld\n", bfdev->info.irq); + break; + } + dev_notice(&pdev->dev, "PCI INTx mask not supported\n"); + /* fall back to no Interrupt, intentional no-break */ + case BF_INTR_MODE_NONE: + bfdev->info.irq = 0; + bfdev->info.num_irq = 0; + bfdev->mode = BF_INTR_MODE_NONE; + break; + + default: + dev_err(&pdev->dev, "invalid IRQ mode %u", bf_intr_mode_default); + err = -EINVAL; + goto fail_clear_pci_master; + } + + pci_set_drvdata(pdev, bfdev); + sprintf(bfdev->name, "bf_%d", bfdev->info.minor); + /* register bf driver */ + err = bf_register_device(&pdev->dev, bfdev); + if (err != 0) + goto fail_release_irq; + + bf_global[bfdev->info.minor].async_queue = NULL; + bf_global[bfdev->info.minor].bfdev = bfdev; + + dev_info(&pdev->dev, "bf device %d registered with irq %ld\n", + bfdev->instance, bfdev->info.irq); + printk(KERN_ALERT "bf probe ok\n"); + return 0; + +fail_release_irq: + pci_set_drvdata(pdev, NULL); + if (bfdev->mode == BF_INTR_MODE_MSIX) { + pci_disable_msix(bfdev->pdev); + kfree(bfdev->info.msix_entries); + bfdev->info.msix_entries = NULL; + } + else if (bfdev->mode == BF_INTR_MODE_MSI) + pci_disable_msi(bfdev->pdev); +fail_clear_pci_master: + pci_clear_master(pdev); +fail_release_iomem: + bf_pci_release_iomem(&bfdev->info); + pci_release_regions(pdev); +fail_pci_disable: + pci_disable_device(pdev); +fail_free: + kfree(bfdev); + + printk(KERN_ERR "bf probe not ok\n"); + return err; +} + +static void +bf_pci_remove(struct pci_dev *pdev) +{ + struct bf_pci_dev *bfdev = pci_get_drvdata(pdev); + struct bf_listener *cur_listener; + + bf_unregister_device(bfdev); + if (bfdev->mode == BF_INTR_MODE_MSIX) { + pci_disable_msix(pdev); + kfree(bfdev->info.msix_entries); + bfdev->info.msix_entries = NULL; + } + else if (bfdev->mode == BF_INTR_MODE_MSI) + pci_disable_msi(pdev); + pci_clear_master(pdev); + bf_pci_release_iomem(&bfdev->info); + pci_release_regions(pdev); + pci_disable_pcie_error_reporting(pdev); + pci_disable_device(pdev); + pci_set_drvdata(pdev, NULL); + bf_global[bfdev->info.minor].bfdev = NULL; + /* existing filep structures in open file(s) must be informed that + * bf_pci_dev is no longer valid */ + spin_lock(&bf_nonisr_lock); + cur_listener = bfdev->listener_head; + while (cur_listener) { + cur_listener->bfdev = NULL; + cur_listener = cur_listener->next; + } + spin_unlock(&bf_nonisr_lock); + kfree(bfdev); +} + +/** + * bf_pci_error_detected - called when PCI error is detected + * @pdev: Pointer to PCI device + * @state: The current pci connection state + * + * called when root complex detects pci error associated with the device + */ +static pci_ers_result_t bf_pci_error_detected(struct pci_dev *pdev, + pci_channel_state_t state) +{ + struct bf_pci_dev *bfdev = pci_get_drvdata(pdev); + int minor; + + if (!bfdev) { + return PCI_ERS_RESULT_NONE; + } + printk(KERN_ERR "pci_err_detected state %d\n", state); + if (state == pci_channel_io_perm_failure || state == pci_channel_io_frozen) { + bfdev->info.pci_error_state = 1; + /* send a signal to the user space program of the error */ + minor = bfdev->info.minor; + if (minor < BF_MAX_DEVICE_CNT && bf_global[minor].async_queue) { + kill_fasync(&bf_global[minor].async_queue, SIGIO, POLL_ERR); + } + return PCI_ERS_RESULT_DISCONNECT; + } else { + return PCI_ERS_RESULT_NONE; + } +} + +/** + * bf_pci_slot_reset - called after the pci bus has been reset. + * @pdev: Pointer to PCI device + * + * Restart the card from scratch, as if from a cold-boot. + */ +static pci_ers_result_t bf_pci_slot_reset(struct pci_dev *pdev) +{ + /* nothing to do for now as we do not expect to get backto normal after + * a pcie link reset + * TBD: fill in this function if tofino can recover after an error + */ + return PCI_ERS_RESULT_DISCONNECT; +} + +/** + * bf_pci_resume - called when kernel thinks the device is up on PCIe. + * @pdev: Pointer to PCI device + * + * This callback is called when the error recovery driver tells us that + * its OK to resume normal operation. + */ +static void bf_pci_resume(struct pci_dev *pdev) +{ + /* this function should never be called for Tofinoi */ + struct bf_pci_dev *bfdev = pci_get_drvdata(pdev); + + printk(KERN_ERR "BF io_resume invoked after pci error\n"); + if (bfdev) { + bfdev->info.pci_error_state = 0; + } +} + +static int +bf_config_intr_mode(char *intr_str) +{ + if (!intr_str) { + pr_info("Use MSIX interrupt by default\n"); + return 0; + } + + if (!strcmp(intr_str, BF_INTR_MODE_MSIX_NAME)) { + bf_intr_mode_default = BF_INTR_MODE_MSIX; + pr_info("Use MSIX interrupt\n"); + } else if (!strcmp(intr_str, BF_INTR_MODE_MSI_NAME)) { + bf_intr_mode_default = BF_INTR_MODE_MSI; + pr_info("Use MSI interrupt\n"); + } else if (!strcmp(intr_str, BF_INTR_MODE_LEGACY_NAME)) { + bf_intr_mode_default = BF_INTR_MODE_LEGACY; + pr_info("Use legacy interrupt\n"); + } else { + pr_info("Error: bad parameter - %s\n", intr_str); + return -EINVAL; + } + + return 0; +} + +static const struct pci_device_id bf_pci_tbl[] = { + {PCI_VDEVICE(BF, TOFINO_DEV_ID_A0), 0}, + {PCI_VDEVICE(BF, TOFINO_DEV_ID_B0), 0}, + /* required last entry */ + { .device = 0 } +}; + +/* PCI bus error handlers */ +static struct pci_error_handlers bf_pci_err_handler = { + .error_detected = bf_pci_error_detected, + .slot_reset = bf_pci_slot_reset, + .resume = bf_pci_resume, +}; + +static struct pci_driver bf_pci_driver = { + .name = "bf", + .id_table = bf_pci_tbl, + .probe = bf_pci_probe, + .remove = bf_pci_remove, + .err_handler = &bf_pci_err_handler +}; + +static int __init +bfdrv_init(void) +{ + int ret; + + ret = bf_config_intr_mode(intr_mode); + if (ret < 0) + return ret; + + spin_lock_init(&bf_nonisr_lock); + return pci_register_driver(&bf_pci_driver); +} + +static void __exit +bfdrv_exit(void) +{ + pci_unregister_driver(&bf_pci_driver); +} + +module_init(bfdrv_init); +module_exit(bfdrv_exit); + +module_param(intr_mode, charp, S_IRUGO); +MODULE_PARM_DESC(intr_mode, +"bf interrupt mode (default=msix):\n" +" " BF_INTR_MODE_MSIX_NAME " Use MSIX interrupt\n" +" " BF_INTR_MODE_MSI_NAME " Use MSI interrupt\n" +" " BF_INTR_MODE_LEGACY_NAME " Use Legacy interrupt\n" +"\n"); + +MODULE_DEVICE_TABLE(pci, bf_pci_tbl); +MODULE_DESCRIPTION("Barefoot Tofino PCI device"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Barefoot Networks"); diff --git a/platform/barefoot/sonic-platform-modules-wnc-osw1800/modules/bf_tun.c b/platform/barefoot/sonic-platform-modules-wnc-osw1800/modules/bf_tun.c new file mode 100644 index 000000000000..a1ba7047baaa --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-wnc-osw1800/modules/bf_tun.c @@ -0,0 +1,2396 @@ +/* + * TUN - Universal TUN/TAP device driver. + * Copyright (C) 1999-2002 Maxim Krasnyansky + * + * 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. + * + * $Id: tun.c,v 1.15 2002/03/01 02:44:24 maxk Exp $ + */ + +/* + * Changes: + * + * Mike Kershaw 2005/08/14 + * Add TUNSETLINK ioctl to set the link encapsulation + * + * Mark Smith + * Use eth_random_addr() for tap MAC address. + * + * Harald Roelle 2004/04/20 + * Fixes in packet dropping, queue length setting and queue wakeup. + * Increased default tx queue length. + * Added ethtool API. + * Minor cleanups + * + * Daniel Podlejski + * Modifications for 2.3.99-pre5 kernel. + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#define DRV_NAME "bf_tun" +#define DRV_VERSION "1.6" +#define DRV_DESCRIPTION "Universal TUN/TAP device driver" +#define DRV_COPYRIGHT "(C) 1999-2004 Max Krasnyansky " + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/* Uncomment to enable debugging */ +/* #define TUN_DEBUG 1 */ + +#define TUN_MINOR1 201 + +#ifdef TUN_DEBUG +static int debug; + +#define tun_debug(level, tun, fmt, args...) \ +do { \ + if (tun->debug) \ + netdev_printk(level, tun->dev, fmt, ##args); \ +} while (0) +#define DBG1(level, fmt, args...) \ +do { \ + if (debug == 2) \ + printk(level fmt, ##args); \ +} while (0) +#else +#define tun_debug(level, tun, fmt, args...) \ +do { \ + if (0) \ + netdev_printk(level, tun->dev, fmt, ##args); \ +} while (0) +#define DBG1(level, fmt, args...) \ +do { \ + if (0) \ + printk(level fmt, ##args); \ +} while (0) +#endif + +#define GOODCOPY_LEN 128 + +#define FLT_EXACT_COUNT 8 +struct tap_filter { + unsigned int count; /* Number of addrs. Zero means disabled */ + u32 mask[2]; /* Mask of the hashed addrs */ + unsigned char addr[FLT_EXACT_COUNT][ETH_ALEN]; +}; + +/* DEFAULT_MAX_NUM_RSS_QUEUES were chosen to let the rx/tx queues allocated for + * the netdevice to be fit in one page. So we can make sure the success of + * memory allocation. TODO: increase the limit. */ +#define MAX_TAP_QUEUES DEFAULT_MAX_NUM_RSS_QUEUES +#define MAX_TAP_FLOWS 4096 + +#define TUN_FLOW_EXPIRE (3 * HZ) + +/* A tun_file connects an open character device to a tuntap netdevice. It + * also contains all socket related structures (except sock_fprog and tap_filter) + * to serve as one transmit queue for tuntap device. The sock_fprog and + * tap_filter were kept in tun_struct since they were used for filtering for the + * netdevice not for a specific queue (at least I didn't see the requirement for + * this). + * + * RCU usage: + * The tun_file and tun_struct are loosely coupled, the pointer from one to the + * other can only be read while rcu_read_lock or rtnl_lock is held. + */ +struct tun_file { + struct sock sk; + struct socket socket; + struct socket_wq wq; + struct tun_struct __rcu *tun; + struct net *net; + struct fasync_struct *fasync; + /* only used for fasnyc */ + unsigned int flags; + union { + u16 queue_index; + unsigned int ifindex; + }; + struct list_head next; + struct tun_struct *detached; +}; + +struct tun_flow_entry { + struct hlist_node hash_link; + struct rcu_head rcu; + struct tun_struct *tun; + + u32 rxhash; + u32 rps_rxhash; + int queue_index; + unsigned long updated; +}; + +#define TUN_NUM_FLOW_ENTRIES 1024 + +/* Since the socket were moved to tun_file, to preserve the behavior of persist + * device, socket filter, sndbuf and vnet header size were restore when the + * file were attached to a persist device. + */ +struct tun_struct { + struct tun_file __rcu *tfiles[MAX_TAP_QUEUES]; + unsigned int numqueues; + unsigned int flags; + kuid_t owner; + kgid_t group; + + struct net_device *dev; + netdev_features_t set_features; +#define TUN_USER_FEATURES (NETIF_F_HW_CSUM|NETIF_F_TSO_ECN|NETIF_F_TSO| \ + NETIF_F_TSO6|NETIF_F_UFO) + + int vnet_hdr_sz; + int sndbuf; + struct tap_filter txflt; + struct sock_fprog fprog; + /* protected by rtnl lock */ + bool filter_attached; +#ifdef TUN_DEBUG + int debug; +#endif + spinlock_t lock; + struct hlist_head flows[TUN_NUM_FLOW_ENTRIES]; + struct timer_list flow_gc_timer; + unsigned long ageing_time; + unsigned int numdisabled; + struct list_head disabled; + void *security; + u32 flow_count; +}; + +static inline u32 tun_hashfn(u32 rxhash) +{ + return rxhash & 0x3ff; +} + +static struct tun_flow_entry *tun_flow_find(struct hlist_head *head, u32 rxhash) +{ + struct tun_flow_entry *e; + + hlist_for_each_entry_rcu(e, head, hash_link) { + if (e->rxhash == rxhash) + return e; + } + return NULL; +} + +static struct tun_flow_entry *tun_flow_create(struct tun_struct *tun, + struct hlist_head *head, + u32 rxhash, u16 queue_index) +{ + struct tun_flow_entry *e = kmalloc(sizeof(*e), GFP_ATOMIC); + + if (e) { + tun_debug(KERN_INFO, tun, "create flow: hash %u index %u\n", + rxhash, queue_index); + e->updated = jiffies; + e->rxhash = rxhash; + e->rps_rxhash = 0; + e->queue_index = queue_index; + e->tun = tun; + hlist_add_head_rcu(&e->hash_link, head); + ++tun->flow_count; + } + return e; +} + +static void tun_flow_delete(struct tun_struct *tun, struct tun_flow_entry *e) +{ + tun_debug(KERN_INFO, tun, "delete flow: hash %u index %u\n", + e->rxhash, e->queue_index); + sock_rps_reset_flow_hash(e->rps_rxhash); + hlist_del_rcu(&e->hash_link); + kfree_rcu(e, rcu); + --tun->flow_count; +} + +static void tun_flow_flush(struct tun_struct *tun) +{ + int i; + + spin_lock_bh(&tun->lock); + for (i = 0; i < TUN_NUM_FLOW_ENTRIES; i++) { + struct tun_flow_entry *e; + struct hlist_node *n; + + hlist_for_each_entry_safe(e, n, &tun->flows[i], hash_link) + tun_flow_delete(tun, e); + } + spin_unlock_bh(&tun->lock); +} + +static void tun_flow_delete_by_queue(struct tun_struct *tun, u16 queue_index) +{ + int i; + + spin_lock_bh(&tun->lock); + for (i = 0; i < TUN_NUM_FLOW_ENTRIES; i++) { + struct tun_flow_entry *e; + struct hlist_node *n; + + hlist_for_each_entry_safe(e, n, &tun->flows[i], hash_link) { + if (e->queue_index == queue_index) + tun_flow_delete(tun, e); + } + } + spin_unlock_bh(&tun->lock); +} + +static void tun_flow_cleanup(unsigned long data) +{ + struct tun_struct *tun = (struct tun_struct *)data; + unsigned long delay = tun->ageing_time; + unsigned long next_timer = jiffies + delay; + unsigned long count = 0; + int i; + + tun_debug(KERN_INFO, tun, "tun_flow_cleanup\n"); + + spin_lock_bh(&tun->lock); + for (i = 0; i < TUN_NUM_FLOW_ENTRIES; i++) { + struct tun_flow_entry *e; + struct hlist_node *n; + + hlist_for_each_entry_safe(e, n, &tun->flows[i], hash_link) { + unsigned long this_timer; + count++; + this_timer = e->updated + delay; + if (time_before_eq(this_timer, jiffies)) + tun_flow_delete(tun, e); + else if (time_before(this_timer, next_timer)) + next_timer = this_timer; + } + } + + if (count) + mod_timer(&tun->flow_gc_timer, round_jiffies_up(next_timer)); + spin_unlock_bh(&tun->lock); +} + +static void tun_flow_update(struct tun_struct *tun, u32 rxhash, + struct tun_file *tfile) +{ + struct hlist_head *head; + struct tun_flow_entry *e; + unsigned long delay = tun->ageing_time; + u16 queue_index = tfile->queue_index; + + if (!rxhash) + return; + else + head = &tun->flows[tun_hashfn(rxhash)]; + + rcu_read_lock(); + + /* We may get a very small possibility of OOO during switching, not + * worth to optimize.*/ + if (tun->numqueues == 1 || tfile->detached) + goto unlock; + + e = tun_flow_find(head, rxhash); + if (likely(e)) { + /* TODO: keep queueing to old queue until it's empty? */ + e->queue_index = queue_index; + e->updated = jiffies; + sock_rps_record_flow_hash(e->rps_rxhash); + } else { + spin_lock_bh(&tun->lock); + if (!tun_flow_find(head, rxhash) && + tun->flow_count < MAX_TAP_FLOWS) + tun_flow_create(tun, head, rxhash, queue_index); + + if (!timer_pending(&tun->flow_gc_timer)) + mod_timer(&tun->flow_gc_timer, + round_jiffies_up(jiffies + delay)); + spin_unlock_bh(&tun->lock); + } + +unlock: + rcu_read_unlock(); +} + +/** + * Save the hash received in the stack receive path and update the + * flow_hash table accordingly. + */ +static inline void tun_flow_save_rps_rxhash(struct tun_flow_entry *e, u32 hash) +{ + if (unlikely(e->rps_rxhash != hash)) { + sock_rps_reset_flow_hash(e->rps_rxhash); + e->rps_rxhash = hash; + } +} + +/* We try to identify a flow through its rxhash first. The reason that + * we do not check rxq no. is because some cards(e.g 82599), chooses + * the rxq based on the txq where the last packet of the flow comes. As + * the userspace application move between processors, we may get a + * different rxq no. here. If we could not get rxhash, then we would + * hope the rxq no. may help here. + */ +static u16 tun_select_queue(struct net_device *dev, struct sk_buff *skb, + void *accel_priv, select_queue_fallback_t fallback) +{ + struct tun_struct *tun = netdev_priv(dev); + struct tun_flow_entry *e; + u32 txq = 0; + u32 numqueues = 0; + + rcu_read_lock(); + numqueues = ACCESS_ONCE(tun->numqueues); + + txq = skb_get_hash(skb); + if (txq) { + e = tun_flow_find(&tun->flows[tun_hashfn(txq)], txq); + if (e) { + tun_flow_save_rps_rxhash(e, txq); + txq = e->queue_index; + } else + /* use multiply and shift instead of expensive divide */ + txq = ((u64)txq * numqueues) >> 32; + } else if (likely(skb_rx_queue_recorded(skb))) { + txq = skb_get_rx_queue(skb); + while (unlikely(txq >= numqueues)) + txq -= numqueues; + } + + rcu_read_unlock(); + return txq; +} + +static inline bool tun_not_capable(struct tun_struct *tun) +{ + const struct cred *cred = current_cred(); + struct net *net = dev_net(tun->dev); + + return ((uid_valid(tun->owner) && !uid_eq(cred->euid, tun->owner)) || + (gid_valid(tun->group) && !in_egroup_p(tun->group))) && + !ns_capable(net->user_ns, CAP_NET_ADMIN); +} + +static void tun_set_real_num_queues(struct tun_struct *tun) +{ + netif_set_real_num_tx_queues(tun->dev, tun->numqueues); + netif_set_real_num_rx_queues(tun->dev, tun->numqueues); +} + +static void tun_disable_queue(struct tun_struct *tun, struct tun_file *tfile) +{ + tfile->detached = tun; + list_add_tail(&tfile->next, &tun->disabled); + ++tun->numdisabled; +} + +static struct tun_struct *tun_enable_queue(struct tun_file *tfile) +{ + struct tun_struct *tun = tfile->detached; + + tfile->detached = NULL; + list_del_init(&tfile->next); + --tun->numdisabled; + return tun; +} + +static void tun_queue_purge(struct tun_file *tfile) +{ + skb_queue_purge(&tfile->sk.sk_receive_queue); + skb_queue_purge(&tfile->sk.sk_error_queue); +} + +static void __tun_detach(struct tun_file *tfile, bool clean) +{ + struct tun_file *ntfile; + struct tun_struct *tun; + + tun = rtnl_dereference(tfile->tun); + + if (tun && !tfile->detached) { + u16 index = tfile->queue_index; + BUG_ON(index >= tun->numqueues); + + rcu_assign_pointer(tun->tfiles[index], + tun->tfiles[tun->numqueues - 1]); + ntfile = rtnl_dereference(tun->tfiles[index]); + ntfile->queue_index = index; + + --tun->numqueues; + if (clean) { + RCU_INIT_POINTER(tfile->tun, NULL); + sock_put(&tfile->sk); + } else + tun_disable_queue(tun, tfile); + + synchronize_net(); + tun_flow_delete_by_queue(tun, tun->numqueues + 1); + /* Drop read queue */ + tun_queue_purge(tfile); + tun_set_real_num_queues(tun); + } else if (tfile->detached && clean) { + tun = tun_enable_queue(tfile); + sock_put(&tfile->sk); + } + + if (clean) { + if (tun && tun->numqueues == 0 && tun->numdisabled == 0) { + netif_carrier_off(tun->dev); + + if (!(tun->flags & TUN_PERSIST) && + tun->dev->reg_state == NETREG_REGISTERED) + unregister_netdevice(tun->dev); + } + + BUG_ON(!test_bit(SOCK_EXTERNALLY_ALLOCATED, + &tfile->socket.flags)); + sk_release_kernel(&tfile->sk); + } +} + +static void tun_detach(struct tun_file *tfile, bool clean) +{ + rtnl_lock(); + __tun_detach(tfile, clean); + rtnl_unlock(); +} + +static void tun_detach_all(struct net_device *dev) +{ + struct tun_struct *tun = netdev_priv(dev); + struct tun_file *tfile, *tmp; + int i, n = tun->numqueues; + + for (i = 0; i < n; i++) { + tfile = rtnl_dereference(tun->tfiles[i]); + BUG_ON(!tfile); + tfile->socket.sk->sk_data_ready(tfile->socket.sk); + RCU_INIT_POINTER(tfile->tun, NULL); + --tun->numqueues; + } + list_for_each_entry(tfile, &tun->disabled, next) { + tfile->socket.sk->sk_data_ready(tfile->socket.sk); + RCU_INIT_POINTER(tfile->tun, NULL); + } + BUG_ON(tun->numqueues != 0); + + synchronize_net(); + for (i = 0; i < n; i++) { + tfile = rtnl_dereference(tun->tfiles[i]); + /* Drop read queue */ + tun_queue_purge(tfile); + sock_put(&tfile->sk); + } + list_for_each_entry_safe(tfile, tmp, &tun->disabled, next) { + tun_enable_queue(tfile); + tun_queue_purge(tfile); + sock_put(&tfile->sk); + } + BUG_ON(tun->numdisabled != 0); + + if (tun->flags & TUN_PERSIST) + module_put(THIS_MODULE); +} + +static int tun_attach(struct tun_struct *tun, struct file *file, bool skip_filter) +{ + struct tun_file *tfile = file->private_data; + int err; + + err = security_tun_dev_attach(tfile->socket.sk, tun->security); + if (err < 0) + goto out; + + err = -EINVAL; + if (rtnl_dereference(tfile->tun) && !tfile->detached) + goto out; + + err = -EBUSY; + if (!(tun->flags & TUN_TAP_MQ) && tun->numqueues == 1) + goto out; + + err = -E2BIG; + if (!tfile->detached && + tun->numqueues + tun->numdisabled == MAX_TAP_QUEUES) + goto out; + + err = 0; + + /* Re-attach the filter to persist device */ + if (!skip_filter && (tun->filter_attached == true)) { + err = __sk_attach_filter(&tun->fprog, tfile->socket.sk, + lockdep_rtnl_is_held()); + if (!err) + goto out; + } + tfile->queue_index = tun->numqueues; + rcu_assign_pointer(tfile->tun, tun); + rcu_assign_pointer(tun->tfiles[tun->numqueues], tfile); + tun->numqueues++; + + if (tfile->detached) + tun_enable_queue(tfile); + else + sock_hold(&tfile->sk); + + tun_set_real_num_queues(tun); + + /* device is allowed to go away first, so no need to hold extra + * refcnt. + */ + +out: + return err; +} + +static struct tun_struct *__tun_get(struct tun_file *tfile) +{ + struct tun_struct *tun; + + rcu_read_lock(); + tun = rcu_dereference(tfile->tun); + if (tun) + dev_hold(tun->dev); + rcu_read_unlock(); + + return tun; +} + +static struct tun_struct *tun_get(struct file *file) +{ + return __tun_get(file->private_data); +} + +static void tun_put(struct tun_struct *tun) +{ + dev_put(tun->dev); +} + +/* TAP filtering */ +static void addr_hash_set(u32 *mask, const u8 *addr) +{ + int n = ether_crc(ETH_ALEN, addr) >> 26; + mask[n >> 5] |= (1 << (n & 31)); +} + +static unsigned int addr_hash_test(const u32 *mask, const u8 *addr) +{ + int n = ether_crc(ETH_ALEN, addr) >> 26; + return mask[n >> 5] & (1 << (n & 31)); +} + +static int update_filter(struct tap_filter *filter, void __user *arg) +{ + struct { u8 u[ETH_ALEN]; } *addr; + struct tun_filter uf; + int err, alen, n, nexact; + + if (copy_from_user(&uf, arg, sizeof(uf))) + return -EFAULT; + + if (!uf.count) { + /* Disabled */ + filter->count = 0; + return 0; + } + + alen = ETH_ALEN * uf.count; + addr = kmalloc(alen, GFP_KERNEL); + if (!addr) + return -ENOMEM; + + if (copy_from_user(addr, arg + sizeof(uf), alen)) { + err = -EFAULT; + goto done; + } + + /* The filter is updated without holding any locks. Which is + * perfectly safe. We disable it first and in the worst + * case we'll accept a few undesired packets. */ + filter->count = 0; + wmb(); + + /* Use first set of addresses as an exact filter */ + for (n = 0; n < uf.count && n < FLT_EXACT_COUNT; n++) + memcpy(filter->addr[n], addr[n].u, ETH_ALEN); + + nexact = n; + + /* Remaining multicast addresses are hashed, + * unicast will leave the filter disabled. */ + memset(filter->mask, 0, sizeof(filter->mask)); + for (; n < uf.count; n++) { + if (!is_multicast_ether_addr(addr[n].u)) { + err = 0; /* no filter */ + goto done; + } + addr_hash_set(filter->mask, addr[n].u); + } + + /* For ALLMULTI just set the mask to all ones. + * This overrides the mask populated above. */ + if ((uf.flags & TUN_FLT_ALLMULTI)) + memset(filter->mask, ~0, sizeof(filter->mask)); + + /* Now enable the filter */ + wmb(); + filter->count = nexact; + + /* Return the number of exact filters */ + err = nexact; + +done: + kfree(addr); + return err; +} + +/* Returns: 0 - drop, !=0 - accept */ +static int run_filter(struct tap_filter *filter, const struct sk_buff *skb) +{ + /* Cannot use eth_hdr(skb) here because skb_mac_hdr() is incorrect + * at this point. */ + struct ethhdr *eh = (struct ethhdr *) skb->data; + int i; + + /* Exact match */ + for (i = 0; i < filter->count; i++) + if (ether_addr_equal(eh->h_dest, filter->addr[i])) + return 1; + + /* Inexact match (multicast only) */ + if (is_multicast_ether_addr(eh->h_dest)) + return addr_hash_test(filter->mask, eh->h_dest); + + return 0; +} + +/* + * Checks whether the packet is accepted or not. + * Returns: 0 - drop, !=0 - accept + */ +static int check_filter(struct tap_filter *filter, const struct sk_buff *skb) +{ + if (!filter->count) + return 1; + + return run_filter(filter, skb); +} + +/* Network device part of the driver */ + +static const struct ethtool_ops tun_ethtool_ops; + +/* Net device detach from fd. */ +static void tun_net_uninit(struct net_device *dev) +{ + tun_detach_all(dev); +} + +/* Net device open. */ +static int tun_net_open(struct net_device *dev) +{ + netif_tx_start_all_queues(dev); + return 0; +} + +/* Net device close. */ +static int tun_net_close(struct net_device *dev) +{ + netif_tx_stop_all_queues(dev); + return 0; +} + +/* Net device start xmit */ +static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev) +{ + struct tun_struct *tun = netdev_priv(dev); + int txq = skb->queue_mapping; + struct tun_file *tfile; + u32 numqueues = 0; + + rcu_read_lock(); + tfile = rcu_dereference(tun->tfiles[txq]); + numqueues = ACCESS_ONCE(tun->numqueues); + + /* Drop packet if interface is not attached */ + if (txq >= numqueues) + goto drop; + + if (numqueues == 1) { + /* Select queue was not called for the skbuff, so we extract the + * RPS hash and save it into the flow_table here. + */ + __u32 rxhash; + + rxhash = skb_get_hash(skb); + if (rxhash) { + struct tun_flow_entry *e; + e = tun_flow_find(&tun->flows[tun_hashfn(rxhash)], + rxhash); + if (e) + tun_flow_save_rps_rxhash(e, rxhash); + } + } + + tun_debug(KERN_INFO, tun, "tun_net_xmit %d\n", skb->len); + + BUG_ON(!tfile); + + /* Drop if the filter does not like it. + * This is a noop if the filter is disabled. + * Filter can be enabled only for the TAP devices. */ + if (!check_filter(&tun->txflt, skb)) + goto drop; + + if (tfile->socket.sk->sk_filter && + sk_filter(tfile->socket.sk, skb)) + goto drop; + + /* Limit the number of packets queued by dividing txq length with the + * number of queues. + */ + if (skb_queue_len(&tfile->socket.sk->sk_receive_queue) * numqueues + >= dev->tx_queue_len) + goto drop; + + if (unlikely(skb_orphan_frags(skb, GFP_ATOMIC))) + goto drop; + + if (skb->sk) { + sock_tx_timestamp(skb->sk, &skb_shinfo(skb)->tx_flags); + sw_tx_timestamp(skb); + } + + /* Orphan the skb - required as we might hang on to it + * for indefinite time. + */ + skb_orphan(skb); + + nf_reset(skb); + + /* Enqueue packet */ + skb_queue_tail(&tfile->socket.sk->sk_receive_queue, skb); + + /* Notify and wake up reader process */ + if (tfile->flags & TUN_FASYNC) + kill_fasync(&tfile->fasync, SIGIO, POLL_IN); + tfile->socket.sk->sk_data_ready(tfile->socket.sk); + + rcu_read_unlock(); + return NETDEV_TX_OK; + +drop: + dev->stats.tx_dropped++; + skb_tx_error(skb); + kfree_skb(skb); + rcu_read_unlock(); + return NETDEV_TX_OK; +} + +static void tun_net_mclist(struct net_device *dev) +{ + /* + * This callback is supposed to deal with mc filter in + * _rx_ path and has nothing to do with the _tx_ path. + * In rx path we always accept everything userspace gives us. + */ +} + +#define MIN_MTU 68 +#define MAX_MTU 65535 + +static int +tun_net_change_mtu(struct net_device *dev, int new_mtu) +{ + if (new_mtu < MIN_MTU || new_mtu + dev->hard_header_len > MAX_MTU) + return -EINVAL; + dev->mtu = new_mtu; + return 0; +} + +static netdev_features_t tun_net_fix_features(struct net_device *dev, + netdev_features_t features) +{ + struct tun_struct *tun = netdev_priv(dev); + + return (features & tun->set_features) | (features & ~TUN_USER_FEATURES); +} + +static int +tun_change_carrier(struct net_device *dev, bool new_carrier) { + if (new_carrier) + netif_carrier_on(dev); + else + netif_carrier_off(dev); + return 0; +} + +#ifdef CONFIG_NET_POLL_CONTROLLER +static void tun_poll_controller(struct net_device *dev) +{ + /* + * Tun only receives frames when: + * 1) the char device endpoint gets data from user space + * 2) the tun socket gets a sendmsg call from user space + * Since both of those are synchronous operations, we are guaranteed + * never to have pending data when we poll for it + * so there is nothing to do here but return. + * We need this though so netpoll recognizes us as an interface that + * supports polling, which enables bridge devices in virt setups to + * still use netconsole + */ + return; +} +#endif +static const struct net_device_ops tun_netdev_ops = { + .ndo_uninit = tun_net_uninit, + .ndo_open = tun_net_open, + .ndo_stop = tun_net_close, + .ndo_start_xmit = tun_net_xmit, + .ndo_change_mtu = tun_net_change_mtu, + .ndo_fix_features = tun_net_fix_features, + .ndo_select_queue = tun_select_queue, +#ifdef CONFIG_NET_POLL_CONTROLLER + .ndo_poll_controller = tun_poll_controller, +#endif +}; + +static const struct net_device_ops tap_netdev_ops = { + .ndo_uninit = tun_net_uninit, + .ndo_open = tun_net_open, + .ndo_stop = tun_net_close, + .ndo_start_xmit = tun_net_xmit, + .ndo_change_mtu = tun_net_change_mtu, + .ndo_fix_features = tun_net_fix_features, + .ndo_set_rx_mode = tun_net_mclist, + .ndo_set_mac_address = eth_mac_addr, + .ndo_validate_addr = eth_validate_addr, + .ndo_select_queue = tun_select_queue, +#ifdef CONFIG_NET_POLL_CONTROLLER + .ndo_poll_controller = tun_poll_controller, +#endif + .ndo_change_carrier = tun_change_carrier, +}; + +static void tun_flow_init(struct tun_struct *tun) +{ + int i; + + for (i = 0; i < TUN_NUM_FLOW_ENTRIES; i++) + INIT_HLIST_HEAD(&tun->flows[i]); + + tun->ageing_time = TUN_FLOW_EXPIRE; + setup_timer(&tun->flow_gc_timer, tun_flow_cleanup, (unsigned long)tun); + mod_timer(&tun->flow_gc_timer, + round_jiffies_up(jiffies + tun->ageing_time)); +} + +static void tun_flow_uninit(struct tun_struct *tun) +{ + del_timer_sync(&tun->flow_gc_timer); + tun_flow_flush(tun); +} + +/* Initialize net device. */ +static void tun_net_init(struct net_device *dev) +{ + struct tun_struct *tun = netdev_priv(dev); + + switch (tun->flags & TUN_TYPE_MASK) { + case TUN_TUN_DEV: + dev->netdev_ops = &tun_netdev_ops; + + /* Point-to-Point TUN Device */ + dev->hard_header_len = 0; + dev->addr_len = 0; + dev->mtu = 1500; + + /* Zero header length */ + dev->type = ARPHRD_NONE; + dev->flags = IFF_POINTOPOINT | IFF_NOARP | IFF_MULTICAST; + dev->tx_queue_len = TUN_READQ_SIZE*2; /* We prefer our own queue length */ + break; + + case TUN_TAP_DEV: + dev->netdev_ops = &tap_netdev_ops; + /* Ethernet TAP Device */ + ether_setup(dev); + dev->priv_flags &= ~IFF_TX_SKB_SHARING; + dev->priv_flags |= IFF_LIVE_ADDR_CHANGE; + + eth_hw_addr_random(dev); + + dev->tx_queue_len = TUN_READQ_SIZE*2; /* We prefer our own queue length */ + break; + } +} + +/* Character device part */ + +/* Poll */ +static unsigned int tun_chr_poll(struct file *file, poll_table *wait) +{ + struct tun_file *tfile = file->private_data; + struct tun_struct *tun = __tun_get(tfile); + struct sock *sk; + unsigned int mask = 0; + + if (!tun) + return POLLERR; + + sk = tfile->socket.sk; + + tun_debug(KERN_INFO, tun, "tun_chr_poll\n"); + + poll_wait(file, sk_sleep(sk), wait); + + if (!skb_queue_empty(&sk->sk_receive_queue)) + mask |= POLLIN | POLLRDNORM; + + if (sock_writeable(sk) || + (!test_and_set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags) && + sock_writeable(sk))) + mask |= POLLOUT | POLLWRNORM; + + if (tun->dev->reg_state != NETREG_REGISTERED) + mask = POLLERR; + + tun_put(tun); + return mask; +} + +/* prepad is the amount to reserve at front. len is length after that. + * linear is a hint as to how much to copy (usually headers). */ +static struct sk_buff *tun_alloc_skb(struct tun_file *tfile, + size_t prepad, size_t len, + size_t linear, int noblock) +{ + struct sock *sk = tfile->socket.sk; + struct sk_buff *skb; + int err; + + /* Under a page? Don't bother with paged skb. */ + if (prepad + len < PAGE_SIZE || !linear) + linear = len; + + skb = sock_alloc_send_pskb(sk, prepad + linear, len - linear, noblock, + &err, 0); + if (!skb) + return ERR_PTR(err); + + skb_reserve(skb, prepad); + skb_put(skb, linear); + skb->data_len = len - linear; + skb->len += len - linear; + + return skb; +} + +/* Get packet from user space buffer */ +static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile, + void *msg_control, const struct iovec *iv, + size_t total_len, size_t count, int noblock) +{ + struct tun_pi pi = { 0, cpu_to_be16(ETH_P_IP) }; + struct sk_buff *skb; + size_t len = total_len, align = NET_SKB_PAD, linear; + struct virtio_net_hdr gso = { 0 }; + int good_linear; + int offset = 0; + int copylen; + bool zerocopy = false; + int err; + u32 rxhash; + + if (!(tun->flags & TUN_NO_PI)) { + if (len < sizeof(pi)) + return -EINVAL; + len -= sizeof(pi); + + if (memcpy_fromiovecend((void *)&pi, iv, 0, sizeof(pi))) + return -EFAULT; + offset += sizeof(pi); + } + + if (tun->flags & TUN_VNET_HDR) { + if (len < tun->vnet_hdr_sz) + return -EINVAL; + len -= tun->vnet_hdr_sz; + + if (memcpy_fromiovecend((void *)&gso, iv, offset, sizeof(gso))) + return -EFAULT; + + if ((gso.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) && + gso.csum_start + gso.csum_offset + 2 > gso.hdr_len) + gso.hdr_len = gso.csum_start + gso.csum_offset + 2; + + if (gso.hdr_len > len) + return -EINVAL; + offset += tun->vnet_hdr_sz; + } + + if ((tun->flags & TUN_TYPE_MASK) == TUN_TAP_DEV) { + align += NET_IP_ALIGN; + if (unlikely(len < ETH_HLEN || + (gso.hdr_len && gso.hdr_len < ETH_HLEN))) + return -EINVAL; + } + + good_linear = SKB_MAX_HEAD(align); + + if (msg_control) { + /* There are 256 bytes to be copied in skb, so there is + * enough room for skb expand head in case it is used. + * The rest of the buffer is mapped from userspace. + */ + copylen = gso.hdr_len ? gso.hdr_len : GOODCOPY_LEN; + if (copylen > good_linear) + copylen = good_linear; + linear = copylen; + if (iov_pages(iv, offset + copylen, count) <= MAX_SKB_FRAGS) + zerocopy = true; + } + + if (!zerocopy) { + copylen = len; + if (gso.hdr_len > good_linear) + linear = good_linear; + else + linear = gso.hdr_len; + } + + skb = tun_alloc_skb(tfile, align, copylen, linear, noblock); + if (IS_ERR(skb)) { + if (PTR_ERR(skb) != -EAGAIN) + tun->dev->stats.rx_dropped++; + return PTR_ERR(skb); + } + + if (zerocopy) + err = zerocopy_sg_from_iovec(skb, iv, offset, count); + else { + err = skb_copy_datagram_from_iovec(skb, 0, iv, offset, len); + if (!err && msg_control) { + struct ubuf_info *uarg = msg_control; + uarg->callback(uarg, false); + } + } + + if (err) { + tun->dev->stats.rx_dropped++; + kfree_skb(skb); + return -EFAULT; + } + + if (gso.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) { + if (!skb_partial_csum_set(skb, gso.csum_start, + gso.csum_offset)) { + tun->dev->stats.rx_frame_errors++; + kfree_skb(skb); + return -EINVAL; + } + } + + switch (tun->flags & TUN_TYPE_MASK) { + case TUN_TUN_DEV: + if (tun->flags & TUN_NO_PI) { + switch (skb->data[0] & 0xf0) { + case 0x40: + pi.proto = htons(ETH_P_IP); + break; + case 0x60: + pi.proto = htons(ETH_P_IPV6); + break; + default: + tun->dev->stats.rx_dropped++; + kfree_skb(skb); + return -EINVAL; + } + } + + skb_reset_mac_header(skb); + skb->protocol = pi.proto; + skb->dev = tun->dev; + break; + case TUN_TAP_DEV: + skb->protocol = eth_type_trans(skb, tun->dev); + break; + } + + skb_reset_network_header(skb); + + if (gso.gso_type != VIRTIO_NET_HDR_GSO_NONE) { + pr_debug("GSO!\n"); + switch (gso.gso_type & ~VIRTIO_NET_HDR_GSO_ECN) { + case VIRTIO_NET_HDR_GSO_TCPV4: + skb_shinfo(skb)->gso_type = SKB_GSO_TCPV4; + break; + case VIRTIO_NET_HDR_GSO_TCPV6: + skb_shinfo(skb)->gso_type = SKB_GSO_TCPV6; + break; + case VIRTIO_NET_HDR_GSO_UDP: + skb_shinfo(skb)->gso_type = SKB_GSO_UDP; + if (skb->protocol == htons(ETH_P_IPV6)) + ipv6_proxy_select_ident(skb); + break; + default: + tun->dev->stats.rx_frame_errors++; + kfree_skb(skb); + return -EINVAL; + } + + if (gso.gso_type & VIRTIO_NET_HDR_GSO_ECN) + skb_shinfo(skb)->gso_type |= SKB_GSO_TCP_ECN; + + skb_shinfo(skb)->gso_size = gso.gso_size; + if (skb_shinfo(skb)->gso_size == 0) { + tun->dev->stats.rx_frame_errors++; + kfree_skb(skb); + return -EINVAL; + } + + /* Header must be checked, and gso_segs computed. */ + skb_shinfo(skb)->gso_type |= SKB_GSO_DODGY; + skb_shinfo(skb)->gso_segs = 0; + } + + /* copy skb_ubuf_info for callback when skb has no error */ + if (zerocopy) { + skb_shinfo(skb)->destructor_arg = msg_control; + skb_shinfo(skb)->tx_flags |= SKBTX_DEV_ZEROCOPY; + skb_shinfo(skb)->tx_flags |= SKBTX_SHARED_FRAG; + } + + skb_probe_transport_header(skb, 0); + + rxhash = skb_get_hash(skb); + netif_rx_ni(skb); + + tun->dev->stats.rx_packets++; + tun->dev->stats.rx_bytes += len; + + tun_flow_update(tun, rxhash, tfile); + return total_len; +} + +static ssize_t tun_chr_aio_write(struct kiocb *iocb, const struct iovec *iv, + unsigned long count, loff_t pos) +{ + struct file *file = iocb->ki_filp; + struct tun_struct *tun = tun_get(file); + struct tun_file *tfile = file->private_data; + ssize_t result; + + if (!tun) + return -EBADFD; + + tun_debug(KERN_INFO, tun, "tun_chr_write %ld\n", count); + + result = tun_get_user(tun, tfile, NULL, iv, iov_length(iv, count), + count, file->f_flags & O_NONBLOCK); + + tun_put(tun); + return result; +} + +/* Put packet to the user space buffer */ +static ssize_t tun_put_user(struct tun_struct *tun, + struct tun_file *tfile, + struct sk_buff *skb, + const struct iovec *iv, int len) +{ + struct tun_pi pi = { 0, skb->protocol }; + ssize_t total = 0; + int vlan_offset = 0, copied; + int vlan_hlen = 0; + + if (vlan_tx_tag_present(skb)) + vlan_hlen = VLAN_HLEN; + + if (!(tun->flags & TUN_NO_PI)) { + if ((len -= sizeof(pi)) < 0) + return -EINVAL; + + if (len < skb->len) { + /* Packet will be striped */ + pi.flags |= TUN_PKT_STRIP; + } + + if (memcpy_toiovecend(iv, (void *) &pi, 0, sizeof(pi))) + return -EFAULT; + total += sizeof(pi); + } + + if (tun->flags & TUN_VNET_HDR) { + struct virtio_net_hdr gso = { 0 }; /* no info leak */ + if ((len -= tun->vnet_hdr_sz) < 0) + return -EINVAL; + + if (skb_is_gso(skb)) { + struct skb_shared_info *sinfo = skb_shinfo(skb); + + /* This is a hint as to how much should be linear. */ + gso.hdr_len = skb_headlen(skb); + gso.gso_size = sinfo->gso_size; + if (sinfo->gso_type & SKB_GSO_TCPV4) + gso.gso_type = VIRTIO_NET_HDR_GSO_TCPV4; + else if (sinfo->gso_type & SKB_GSO_TCPV6) + gso.gso_type = VIRTIO_NET_HDR_GSO_TCPV6; + else if (sinfo->gso_type & SKB_GSO_UDP) + gso.gso_type = VIRTIO_NET_HDR_GSO_UDP; + else { + pr_err("unexpected GSO type: " + "0x%x, gso_size %d, hdr_len %d\n", + sinfo->gso_type, gso.gso_size, + gso.hdr_len); + print_hex_dump(KERN_ERR, "tun: ", + DUMP_PREFIX_NONE, + 16, 1, skb->head, + min((int)gso.hdr_len, 64), true); + WARN_ON_ONCE(1); + return -EINVAL; + } + if (sinfo->gso_type & SKB_GSO_TCP_ECN) + gso.gso_type |= VIRTIO_NET_HDR_GSO_ECN; + } else + gso.gso_type = VIRTIO_NET_HDR_GSO_NONE; + + if (skb->ip_summed == CHECKSUM_PARTIAL) { + gso.flags = VIRTIO_NET_HDR_F_NEEDS_CSUM; + gso.csum_start = skb_checksum_start_offset(skb) + + vlan_hlen; + gso.csum_offset = skb->csum_offset; + } else if (skb->ip_summed == CHECKSUM_UNNECESSARY) { + gso.flags = VIRTIO_NET_HDR_F_DATA_VALID; + } /* else everything is zero */ + + if (unlikely(memcpy_toiovecend(iv, (void *)&gso, total, + sizeof(gso)))) + return -EFAULT; + total += tun->vnet_hdr_sz; + } + + copied = total; + len = min_t(int, skb->len + vlan_hlen, len); + total += skb->len + vlan_hlen; + if (vlan_hlen) { + int copy, ret; + struct { + __be16 h_vlan_proto; + __be16 h_vlan_TCI; + } veth; + + veth.h_vlan_proto = skb->vlan_proto; + veth.h_vlan_TCI = htons(vlan_tx_tag_get(skb)); + + vlan_offset = offsetof(struct vlan_ethhdr, h_vlan_proto); + + copy = min_t(int, vlan_offset, len); + ret = skb_copy_datagram_const_iovec(skb, 0, iv, copied, copy); + len -= copy; + copied += copy; + if (ret || !len) + goto done; + + copy = min_t(int, sizeof(veth), len); + ret = memcpy_toiovecend(iv, (void *)&veth, copied, copy); + len -= copy; + copied += copy; + if (ret || !len) + goto done; + } + + skb_copy_datagram_const_iovec(skb, vlan_offset, iv, copied, len); + +done: + tun->dev->stats.tx_packets++; + tun->dev->stats.tx_bytes += len; + + return total; +} + +static ssize_t tun_do_read(struct tun_struct *tun, struct tun_file *tfile, + const struct iovec *iv, ssize_t len, int noblock) +{ + struct sk_buff *skb; + ssize_t ret = 0; + int peeked, err, off = 0; + + tun_debug(KERN_INFO, tun, "tun_do_read\n"); + + if (!len) + return ret; + + if (tun->dev->reg_state != NETREG_REGISTERED) + return -EIO; + + /* Read frames from queue */ + skb = __skb_recv_datagram(tfile->socket.sk, noblock ? MSG_DONTWAIT : 0, + &peeked, &off, &err); + if (skb) { + ret = tun_put_user(tun, tfile, skb, iv, len); + kfree_skb(skb); + } else + ret = err; + + return ret; +} + +static ssize_t tun_chr_aio_read(struct kiocb *iocb, const struct iovec *iv, + unsigned long count, loff_t pos) +{ + struct file *file = iocb->ki_filp; + struct tun_file *tfile = file->private_data; + struct tun_struct *tun = __tun_get(tfile); + ssize_t len, ret; + + if (!tun) + return -EBADFD; + len = iov_length(iv, count); + if (len < 0) { + ret = -EINVAL; + goto out; + } + + ret = tun_do_read(tun, tfile, iv, len, + file->f_flags & O_NONBLOCK); + ret = min_t(ssize_t, ret, len); + if (ret > 0) + iocb->ki_pos = ret; +out: + tun_put(tun); + return ret; +} + +static void tun_free_netdev(struct net_device *dev) +{ + struct tun_struct *tun = netdev_priv(dev); + + BUG_ON(!(list_empty(&tun->disabled))); + tun_flow_uninit(tun); + security_tun_dev_free_security(tun->security); + free_netdev(dev); +} + +static void tun_setup(struct net_device *dev) +{ + struct tun_struct *tun = netdev_priv(dev); + + tun->owner = INVALID_UID; + tun->group = INVALID_GID; + + dev->ethtool_ops = &tun_ethtool_ops; + dev->destructor = tun_free_netdev; +} + +/* Trivial set of netlink ops to allow deleting tun or tap + * device with netlink. + */ +static int tun_validate(struct nlattr *tb[], struct nlattr *data[]) +{ + return -EINVAL; +} + +static struct rtnl_link_ops tun_link_ops __read_mostly = { + .kind = DRV_NAME, + .priv_size = sizeof(struct tun_struct), + .setup = tun_setup, + .validate = tun_validate, +}; + +static void tun_sock_write_space(struct sock *sk) +{ + struct tun_file *tfile; + wait_queue_head_t *wqueue; + + if (!sock_writeable(sk)) + return; + + if (!test_and_clear_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags)) + return; + + wqueue = sk_sleep(sk); + if (wqueue && waitqueue_active(wqueue)) + wake_up_interruptible_sync_poll(wqueue, POLLOUT | + POLLWRNORM | POLLWRBAND); + + tfile = container_of(sk, struct tun_file, sk); + kill_fasync(&tfile->fasync, SIGIO, POLL_OUT); +} + +static int tun_sendmsg(struct kiocb *iocb, struct socket *sock, + struct msghdr *m, size_t total_len) +{ + int ret; + struct tun_file *tfile = container_of(sock, struct tun_file, socket); + struct tun_struct *tun = __tun_get(tfile); + + if (!tun) + return -EBADFD; + ret = tun_get_user(tun, tfile, m->msg_control, m->msg_iov, total_len, + m->msg_iovlen, m->msg_flags & MSG_DONTWAIT); + tun_put(tun); + return ret; +} + +static int tun_recvmsg(struct kiocb *iocb, struct socket *sock, + struct msghdr *m, size_t total_len, + int flags) +{ + struct tun_file *tfile = container_of(sock, struct tun_file, socket); + struct tun_struct *tun = __tun_get(tfile); + int ret; + + if (!tun) + return -EBADFD; + + if (flags & ~(MSG_DONTWAIT|MSG_TRUNC|MSG_ERRQUEUE)) { + ret = -EINVAL; + goto out; + } + if (flags & MSG_ERRQUEUE) { + ret = sock_recv_errqueue(sock->sk, m, total_len, + SOL_PACKET, TUN_TX_TIMESTAMP); + goto out; + } + ret = tun_do_read(tun, tfile, m->msg_iov, total_len, + flags & MSG_DONTWAIT); + if (ret > total_len) { + m->msg_flags |= MSG_TRUNC; + ret = flags & MSG_TRUNC ? ret : total_len; + } +out: + tun_put(tun); + return ret; +} + +static int tun_release(struct socket *sock) +{ + if (sock->sk) + sock_put(sock->sk); + return 0; +} + +/* Ops structure to mimic raw sockets with tun */ +static const struct proto_ops tun_socket_ops = { + .sendmsg = tun_sendmsg, + .recvmsg = tun_recvmsg, + .release = tun_release, +}; + +static struct proto tun_proto = { + .name = "bf_tun", + .owner = THIS_MODULE, + .obj_size = sizeof(struct tun_file), +}; + +static int tun_flags(struct tun_struct *tun) +{ + int flags = 0; + + if (tun->flags & TUN_TUN_DEV) + flags |= IFF_TUN; + else + flags |= IFF_TAP; + + if (tun->flags & TUN_NO_PI) + flags |= IFF_NO_PI; + + /* This flag has no real effect. We track the value for backwards + * compatibility. + */ + if (tun->flags & TUN_ONE_QUEUE) + flags |= IFF_ONE_QUEUE; + + if (tun->flags & TUN_VNET_HDR) + flags |= IFF_VNET_HDR; + + if (tun->flags & TUN_TAP_MQ) + flags |= IFF_MULTI_QUEUE; + + if (tun->flags & TUN_PERSIST) + flags |= IFF_PERSIST; + + return flags; +} + +static ssize_t tun_show_flags(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct tun_struct *tun = netdev_priv(to_net_dev(dev)); + return sprintf(buf, "0x%x\n", tun_flags(tun)); +} + +static ssize_t tun_show_owner(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct tun_struct *tun = netdev_priv(to_net_dev(dev)); + return uid_valid(tun->owner)? + sprintf(buf, "%u\n", + from_kuid_munged(current_user_ns(), tun->owner)): + sprintf(buf, "-1\n"); +} + +static ssize_t tun_show_group(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct tun_struct *tun = netdev_priv(to_net_dev(dev)); + return gid_valid(tun->group) ? + sprintf(buf, "%u\n", + from_kgid_munged(current_user_ns(), tun->group)): + sprintf(buf, "-1\n"); +} + +static DEVICE_ATTR(tun_flags, 0444, tun_show_flags, NULL); +static DEVICE_ATTR(owner, 0444, tun_show_owner, NULL); +static DEVICE_ATTR(group, 0444, tun_show_group, NULL); + +static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) +{ + struct tun_struct *tun; + struct tun_file *tfile = file->private_data; + struct net_device *dev; + int err; + + if (tfile->detached) + return -EINVAL; + + dev = __dev_get_by_name(net, ifr->ifr_name); + if (dev) { + if (ifr->ifr_flags & IFF_TUN_EXCL) + return -EBUSY; + if ((ifr->ifr_flags & IFF_TUN) && dev->netdev_ops == &tun_netdev_ops) + tun = netdev_priv(dev); + else if ((ifr->ifr_flags & IFF_TAP) && dev->netdev_ops == &tap_netdev_ops) + tun = netdev_priv(dev); + else + return -EINVAL; + + if (!!(ifr->ifr_flags & IFF_MULTI_QUEUE) != + !!(tun->flags & TUN_TAP_MQ)) + return -EINVAL; + + if (tun_not_capable(tun)) + return -EPERM; + err = security_tun_dev_open(tun->security); + if (err < 0) + return err; + + err = tun_attach(tun, file, ifr->ifr_flags & IFF_NOFILTER); + if (err < 0) + return err; + + if (tun->flags & TUN_TAP_MQ && + (tun->numqueues + tun->numdisabled > 1)) { + /* One or more queue has already been attached, no need + * to initialize the device again. + */ + return 0; + } + } + else { + char *name; + unsigned long flags = 0; + int queues = ifr->ifr_flags & IFF_MULTI_QUEUE ? + MAX_TAP_QUEUES : 1; + + if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) + return -EPERM; + err = security_tun_dev_create(); + if (err < 0) + return err; + + /* Set dev type */ + if (ifr->ifr_flags & IFF_TUN) { + /* TUN device */ + flags |= TUN_TUN_DEV; + name = "tun%d"; + } else if (ifr->ifr_flags & IFF_TAP) { + /* TAP device */ + flags |= TUN_TAP_DEV; + name = "tap%d"; + } else + return -EINVAL; + + if (*ifr->ifr_name) + name = ifr->ifr_name; + + dev = alloc_netdev_mqs(sizeof(struct tun_struct), name, + tun_setup, queues, queues); + + if (!dev) + return -ENOMEM; + + dev_net_set(dev, net); + dev->rtnl_link_ops = &tun_link_ops; + dev->ifindex = tfile->ifindex; + + tun = netdev_priv(dev); + tun->dev = dev; + tun->flags = flags; + tun->txflt.count = 0; + tun->vnet_hdr_sz = sizeof(struct virtio_net_hdr); + + tun->filter_attached = false; + tun->sndbuf = tfile->socket.sk->sk_sndbuf; + + spin_lock_init(&tun->lock); + + err = security_tun_dev_alloc_security(&tun->security); + if (err < 0) + goto err_free_dev; + + tun_net_init(dev); + tun_flow_init(tun); + + dev->hw_features = NETIF_F_SG | NETIF_F_FRAGLIST | + TUN_USER_FEATURES | NETIF_F_HW_VLAN_CTAG_TX | + NETIF_F_HW_VLAN_STAG_TX; + dev->features = dev->hw_features; + dev->vlan_features = dev->features & + ~(NETIF_F_HW_VLAN_CTAG_TX | + NETIF_F_HW_VLAN_STAG_TX); + + INIT_LIST_HEAD(&tun->disabled); + err = tun_attach(tun, file, false); + if (err < 0) + goto err_free_flow; + + err = register_netdevice(tun->dev); + if (err < 0) + goto err_detach; + + if (device_create_file(&tun->dev->dev, &dev_attr_tun_flags) || + device_create_file(&tun->dev->dev, &dev_attr_owner) || + device_create_file(&tun->dev->dev, &dev_attr_group)) + pr_err("Failed to create tun sysfs files\n"); + } + + netif_carrier_on(tun->dev); + + tun_debug(KERN_INFO, tun, "tun_set_iff\n"); + + if (ifr->ifr_flags & IFF_NO_PI) + tun->flags |= TUN_NO_PI; + else + tun->flags &= ~TUN_NO_PI; + + /* This flag has no real effect. We track the value for backwards + * compatibility. + */ + if (ifr->ifr_flags & IFF_ONE_QUEUE) + tun->flags |= TUN_ONE_QUEUE; + else + tun->flags &= ~TUN_ONE_QUEUE; + + if (ifr->ifr_flags & IFF_VNET_HDR) + tun->flags |= TUN_VNET_HDR; + else + tun->flags &= ~TUN_VNET_HDR; + + if (ifr->ifr_flags & IFF_MULTI_QUEUE) + tun->flags |= TUN_TAP_MQ; + else + tun->flags &= ~TUN_TAP_MQ; + + /* Make sure persistent devices do not get stuck in + * xoff state. + */ + if (netif_running(tun->dev)) + netif_tx_wake_all_queues(tun->dev); + + strcpy(ifr->ifr_name, tun->dev->name); + return 0; + +err_detach: + tun_detach_all(dev); +err_free_flow: + tun_flow_uninit(tun); + security_tun_dev_free_security(tun->security); +err_free_dev: + free_netdev(dev); + return err; +} + +static void tun_get_iff(struct net *net, struct tun_struct *tun, + struct ifreq *ifr) +{ + tun_debug(KERN_INFO, tun, "tun_get_iff\n"); + + strcpy(ifr->ifr_name, tun->dev->name); + + ifr->ifr_flags = tun_flags(tun); + +} + +/* This is like a cut-down ethtool ops, except done via tun fd so no + * privs required. */ +static int set_offload(struct tun_struct *tun, unsigned long arg) +{ + netdev_features_t features = 0; + + if (arg & TUN_F_CSUM) { + features |= NETIF_F_HW_CSUM; + arg &= ~TUN_F_CSUM; + + if (arg & (TUN_F_TSO4|TUN_F_TSO6)) { + if (arg & TUN_F_TSO_ECN) { + features |= NETIF_F_TSO_ECN; + arg &= ~TUN_F_TSO_ECN; + } + if (arg & TUN_F_TSO4) + features |= NETIF_F_TSO; + if (arg & TUN_F_TSO6) + features |= NETIF_F_TSO6; + arg &= ~(TUN_F_TSO4|TUN_F_TSO6); + } + + if (arg & TUN_F_UFO) { + features |= NETIF_F_UFO; + arg &= ~TUN_F_UFO; + } + } + + /* This gives the user a way to test for new features in future by + * trying to set them. */ + if (arg) + return -EINVAL; + + tun->set_features = features; + netdev_update_features(tun->dev); + + return 0; +} + +static void tun_detach_filter(struct tun_struct *tun, int n) +{ + int i; + struct tun_file *tfile; + + for (i = 0; i < n; i++) { + tfile = rtnl_dereference(tun->tfiles[i]); + __sk_detach_filter(tfile->socket.sk, lockdep_rtnl_is_held()); + } + + tun->filter_attached = false; +} + +static int tun_attach_filter(struct tun_struct *tun) +{ + int i, ret = 0; + struct tun_file *tfile; + + for (i = 0; i < tun->numqueues; i++) { + tfile = rtnl_dereference(tun->tfiles[i]); + ret = __sk_attach_filter(&tun->fprog, tfile->socket.sk, + lockdep_rtnl_is_held()); + if (ret) { + tun_detach_filter(tun, i); + return ret; + } + } + + tun->filter_attached = true; + return ret; +} + +static void tun_set_sndbuf(struct tun_struct *tun) +{ + struct tun_file *tfile; + int i; + + for (i = 0; i < tun->numqueues; i++) { + tfile = rtnl_dereference(tun->tfiles[i]); + tfile->socket.sk->sk_sndbuf = tun->sndbuf; + } +} + +static int tun_set_queue(struct file *file, struct ifreq *ifr) +{ + struct tun_file *tfile = file->private_data; + struct tun_struct *tun; + int ret = 0; + + rtnl_lock(); + + if (ifr->ifr_flags & IFF_ATTACH_QUEUE) { + tun = tfile->detached; + if (!tun) { + ret = -EINVAL; + goto unlock; + } + ret = security_tun_dev_attach_queue(tun->security); + if (ret < 0) + goto unlock; + ret = tun_attach(tun, file, false); + } else if (ifr->ifr_flags & IFF_DETACH_QUEUE) { + tun = rtnl_dereference(tfile->tun); + if (!tun || !(tun->flags & TUN_TAP_MQ) || tfile->detached) + ret = -EINVAL; + else + __tun_detach(tfile, false); + } else + ret = -EINVAL; + +unlock: + rtnl_unlock(); + return ret; +} + +static long __tun_chr_ioctl(struct file *file, unsigned int cmd, + unsigned long arg, int ifreq_len) +{ + struct tun_file *tfile = file->private_data; + struct tun_struct *tun; + void __user* argp = (void __user*)arg; + struct ifreq ifr; + kuid_t owner; + kgid_t group; + int sndbuf; + int vnet_hdr_sz; + unsigned int ifindex; + int ret; + + if (cmd == TUNSETIFF || cmd == TUNSETQUEUE || _IOC_TYPE(cmd) == 0x89) { + if (copy_from_user(&ifr, argp, ifreq_len)) + return -EFAULT; + } else { + memset(&ifr, 0, sizeof(ifr)); + } + if (cmd == TUNGETFEATURES) { + /* Currently this just means: "what IFF flags are valid?". + * This is needed because we never checked for invalid flags on + * TUNSETIFF. */ + return put_user(IFF_TUN | IFF_TAP | IFF_NO_PI | IFF_ONE_QUEUE | + IFF_VNET_HDR | IFF_MULTI_QUEUE, + (unsigned int __user*)argp); + } else if (cmd == TUNSETQUEUE) + return tun_set_queue(file, &ifr); + + ret = 0; + rtnl_lock(); + + tun = __tun_get(tfile); + if (cmd == TUNSETIFF && !tun) { + ifr.ifr_name[IFNAMSIZ-1] = '\0'; + + ret = tun_set_iff(tfile->net, file, &ifr); + + if (ret) + goto unlock; + + if (copy_to_user(argp, &ifr, ifreq_len)) + ret = -EFAULT; + goto unlock; + } + if (cmd == TUNSETIFINDEX) { + ret = -EPERM; + if (tun) + goto unlock; + + ret = -EFAULT; + if (copy_from_user(&ifindex, argp, sizeof(ifindex))) + goto unlock; + + ret = 0; + tfile->ifindex = ifindex; + goto unlock; + } + + ret = -EBADFD; + if (!tun) + goto unlock; + + tun_debug(KERN_INFO, tun, "tun_chr_ioctl cmd %u\n", cmd); + + ret = 0; + switch (cmd) { + case TUNGETIFF: + tun_get_iff(current->nsproxy->net_ns, tun, &ifr); + + if (tfile->detached) + ifr.ifr_flags |= IFF_DETACH_QUEUE; + if (!tfile->socket.sk->sk_filter) + ifr.ifr_flags |= IFF_NOFILTER; + + if (copy_to_user(argp, &ifr, ifreq_len)) + ret = -EFAULT; + break; + + case TUNSETNOCSUM: + /* Disable/Enable checksum */ + + /* [unimplemented] */ + tun_debug(KERN_INFO, tun, "ignored: set checksum %s\n", + arg ? "disabled" : "enabled"); + break; + + case TUNSETPERSIST: + /* Disable/Enable persist mode. Keep an extra reference to the + * module to prevent the module being unprobed. + */ + if (arg && !(tun->flags & TUN_PERSIST)) { + tun->flags |= TUN_PERSIST; + __module_get(THIS_MODULE); + } + if (!arg && (tun->flags & TUN_PERSIST)) { + tun->flags &= ~TUN_PERSIST; + module_put(THIS_MODULE); + } + + tun_debug(KERN_INFO, tun, "persist %s\n", + arg ? "enabled" : "disabled"); + break; + + case TUNSETOWNER: + /* Set owner of the device */ + owner = make_kuid(current_user_ns(), arg); + if (!uid_valid(owner)) { + ret = -EINVAL; + break; + } + tun->owner = owner; + tun_debug(KERN_INFO, tun, "owner set to %u\n", + from_kuid(&init_user_ns, tun->owner)); + break; + + case TUNSETGROUP: + /* Set group of the device */ + group = make_kgid(current_user_ns(), arg); + if (!gid_valid(group)) { + ret = -EINVAL; + break; + } + tun->group = group; + tun_debug(KERN_INFO, tun, "group set to %u\n", + from_kgid(&init_user_ns, tun->group)); + break; + + case TUNSETLINK: + /* Only allow setting the type when the interface is down */ + if (tun->dev->flags & IFF_UP) { + tun_debug(KERN_INFO, tun, + "Linktype set failed because interface is up\n"); + ret = -EBUSY; + } else { + tun->dev->type = (int) arg; + tun_debug(KERN_INFO, tun, "linktype set to %d\n", + tun->dev->type); + ret = 0; + } + break; + +#ifdef TUN_DEBUG + case TUNSETDEBUG: + tun->debug = arg; + break; +#endif + case TUNSETOFFLOAD: + ret = set_offload(tun, arg); + break; + + case TUNSETTXFILTER: + /* Can be set only for TAPs */ + ret = -EINVAL; + if ((tun->flags & TUN_TYPE_MASK) != TUN_TAP_DEV) + break; + ret = update_filter(&tun->txflt, (void __user *)arg); + break; + + case SIOCGIFHWADDR: + /* Get hw address */ + memcpy(ifr.ifr_hwaddr.sa_data, tun->dev->dev_addr, ETH_ALEN); + ifr.ifr_hwaddr.sa_family = tun->dev->type; + if (copy_to_user(argp, &ifr, ifreq_len)) + ret = -EFAULT; + break; + + case SIOCSIFHWADDR: + /* Set hw address */ + tun_debug(KERN_DEBUG, tun, "set hw address: %pM\n", + ifr.ifr_hwaddr.sa_data); + + ret = dev_set_mac_address(tun->dev, &ifr.ifr_hwaddr); + break; + + case TUNGETSNDBUF: + sndbuf = tfile->socket.sk->sk_sndbuf; + if (copy_to_user(argp, &sndbuf, sizeof(sndbuf))) + ret = -EFAULT; + break; + + case TUNSETSNDBUF: + if (copy_from_user(&sndbuf, argp, sizeof(sndbuf))) { + ret = -EFAULT; + break; + } + + tun->sndbuf = sndbuf; + tun_set_sndbuf(tun); + break; + + case TUNGETVNETHDRSZ: + vnet_hdr_sz = tun->vnet_hdr_sz; + if (copy_to_user(argp, &vnet_hdr_sz, sizeof(vnet_hdr_sz))) + ret = -EFAULT; + break; + + case TUNSETVNETHDRSZ: + if (copy_from_user(&vnet_hdr_sz, argp, sizeof(vnet_hdr_sz))) { + ret = -EFAULT; + break; + } + if (vnet_hdr_sz < (int)sizeof(struct virtio_net_hdr)) { + ret = -EINVAL; + break; + } + + tun->vnet_hdr_sz = vnet_hdr_sz; + break; + + case TUNATTACHFILTER: + /* Can be set only for TAPs */ + ret = -EINVAL; + if ((tun->flags & TUN_TYPE_MASK) != TUN_TAP_DEV) + break; + ret = -EFAULT; + if (copy_from_user(&tun->fprog, argp, sizeof(tun->fprog))) + break; + + ret = tun_attach_filter(tun); + break; + + case TUNDETACHFILTER: + /* Can be set only for TAPs */ + ret = -EINVAL; + if ((tun->flags & TUN_TYPE_MASK) != TUN_TAP_DEV) + break; + ret = 0; + tun_detach_filter(tun, tun->numqueues); + break; + + case TUNGETFILTER: + ret = -EINVAL; + if ((tun->flags & TUN_TYPE_MASK) != TUN_TAP_DEV) + break; + ret = -EFAULT; + if (copy_to_user(argp, &tun->fprog, sizeof(tun->fprog))) + break; + ret = 0; + break; + + default: + ret = -EINVAL; + break; + } + +unlock: + rtnl_unlock(); + if (tun) + tun_put(tun); + return ret; +} + +static long tun_chr_ioctl(struct file *file, + unsigned int cmd, unsigned long arg) +{ + return __tun_chr_ioctl(file, cmd, arg, sizeof (struct ifreq)); +} + +#ifdef CONFIG_COMPAT +static long tun_chr_compat_ioctl(struct file *file, + unsigned int cmd, unsigned long arg) +{ + switch (cmd) { + case TUNSETIFF: + case TUNGETIFF: + case TUNSETTXFILTER: + case TUNGETSNDBUF: + case TUNSETSNDBUF: + case SIOCGIFHWADDR: + case SIOCSIFHWADDR: + arg = (unsigned long)compat_ptr(arg); + break; + default: + arg = (compat_ulong_t)arg; + break; + } + + /* + * compat_ifreq is shorter than ifreq, so we must not access beyond + * the end of that structure. All fields that are used in this + * driver are compatible though, we don't need to convert the + * contents. + */ + return __tun_chr_ioctl(file, cmd, arg, sizeof(struct compat_ifreq)); +} +#endif /* CONFIG_COMPAT */ + +static int tun_chr_fasync(int fd, struct file *file, int on) +{ + struct tun_file *tfile = file->private_data; + int ret; + + if ((ret = fasync_helper(fd, file, on, &tfile->fasync)) < 0) + goto out; + + if (on) { + ret = __f_setown(file, task_pid(current), PIDTYPE_PID, 0); + if (ret) + goto out; + tfile->flags |= TUN_FASYNC; + } else + tfile->flags &= ~TUN_FASYNC; + ret = 0; +out: + return ret; +} + +static int tun_chr_open(struct inode *inode, struct file * file) +{ + struct tun_file *tfile; + + DBG1(KERN_INFO, "tunX: tun_chr_open\n"); + + tfile = (struct tun_file *)sk_alloc(&init_net, AF_UNSPEC, GFP_KERNEL, + &tun_proto); + if (!tfile) + return -ENOMEM; + RCU_INIT_POINTER(tfile->tun, NULL); + tfile->net = get_net(current->nsproxy->net_ns); + tfile->flags = 0; + tfile->ifindex = 0; + + init_waitqueue_head(&tfile->wq.wait); + RCU_INIT_POINTER(tfile->socket.wq, &tfile->wq); + + tfile->socket.file = file; + tfile->socket.ops = &tun_socket_ops; + + sock_init_data(&tfile->socket, &tfile->sk); + sk_change_net(&tfile->sk, tfile->net); + + tfile->sk.sk_write_space = tun_sock_write_space; + tfile->sk.sk_sndbuf = INT_MAX; + + file->private_data = tfile; + set_bit(SOCK_EXTERNALLY_ALLOCATED, &tfile->socket.flags); + INIT_LIST_HEAD(&tfile->next); + + sock_set_flag(&tfile->sk, SOCK_ZEROCOPY); + + return 0; +} + +static int tun_chr_close(struct inode *inode, struct file *file) +{ + struct tun_file *tfile = file->private_data; + struct net *net = tfile->net; + + tun_detach(tfile, true); + put_net(net); + + return 0; +} + +#ifdef CONFIG_PROC_FS +static int tun_chr_show_fdinfo(struct seq_file *m, struct file *f) +{ + struct tun_struct *tun; + struct ifreq ifr; + + memset(&ifr, 0, sizeof(ifr)); + + rtnl_lock(); + tun = tun_get(f); + if (tun) + tun_get_iff(current->nsproxy->net_ns, tun, &ifr); + rtnl_unlock(); + + if (tun) + tun_put(tun); + + return seq_printf(m, "iff:\t%s\n", ifr.ifr_name); +} +#endif + +static const struct file_operations tun_fops = { + .owner = THIS_MODULE, + .llseek = no_llseek, + .read = do_sync_read, + .aio_read = tun_chr_aio_read, + .write = do_sync_write, + .aio_write = tun_chr_aio_write, + .poll = tun_chr_poll, + .unlocked_ioctl = tun_chr_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = tun_chr_compat_ioctl, +#endif + .open = tun_chr_open, + .release = tun_chr_close, + .fasync = tun_chr_fasync, +#ifdef CONFIG_PROC_FS + .show_fdinfo = tun_chr_show_fdinfo, +#endif +}; + +static struct miscdevice tun_miscdev = { + .minor = (TUN_MINOR1), + .name = "bf_tun", + .nodename = "net/bf_tun", + .fops = &tun_fops, +}; + +/* ethtool interface */ + +static int tun_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + cmd->supported = 0; + cmd->advertising = 0; + ethtool_cmd_speed_set(cmd, SPEED_10); + cmd->duplex = DUPLEX_FULL; + cmd->port = PORT_TP; + cmd->phy_address = 0; + cmd->transceiver = XCVR_INTERNAL; + cmd->autoneg = AUTONEG_DISABLE; + cmd->maxtxpkt = 0; + cmd->maxrxpkt = 0; + return 0; +} + +static void tun_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) +{ + struct tun_struct *tun = netdev_priv(dev); + + strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); + strlcpy(info->version, DRV_VERSION, sizeof(info->version)); + + switch (tun->flags & TUN_TYPE_MASK) { + case TUN_TUN_DEV: + strlcpy(info->bus_info, "bf_tun", sizeof(info->bus_info)); + break; + case TUN_TAP_DEV: + strlcpy(info->bus_info, "tap", sizeof(info->bus_info)); + break; + } +} + +static u32 tun_get_msglevel(struct net_device *dev) +{ +#ifdef TUN_DEBUG + struct tun_struct *tun = netdev_priv(dev); + return tun->debug; +#else + return -EOPNOTSUPP; +#endif +} + +static void tun_set_msglevel(struct net_device *dev, u32 value) +{ +#ifdef TUN_DEBUG + struct tun_struct *tun = netdev_priv(dev); + tun->debug = value; +#endif +} + +static const struct ethtool_ops tun_ethtool_ops = { + .get_settings = tun_get_settings, + .get_drvinfo = tun_get_drvinfo, + .get_msglevel = tun_get_msglevel, + .set_msglevel = tun_set_msglevel, + .get_link = ethtool_op_get_link, + .get_ts_info = ethtool_op_get_ts_info, +}; + + +static int __init tun_init(void) +{ + int ret = 0; + + pr_info("%s, %s\n", DRV_DESCRIPTION, DRV_VERSION); + pr_info("%s\n", DRV_COPYRIGHT); + + ret = rtnl_link_register(&tun_link_ops); + if (ret) { + pr_err("Can't register link_ops\n"); + goto err_linkops; + } + + ret = misc_register(&tun_miscdev); + if (ret) { + pr_err("Can't register misc device %d\n", (TUN_MINOR1)); + goto err_misc; + } + return 0; +err_misc: + rtnl_link_unregister(&tun_link_ops); +err_linkops: + return ret; +} + +static void tun_cleanup(void) +{ + misc_deregister(&tun_miscdev); + rtnl_link_unregister(&tun_link_ops); +} + +/* Get an underlying socket object from tun file. Returns error unless file is + * attached to a device. The returned object works like a packet socket, it + * can be used for sock_sendmsg/sock_recvmsg. The caller is responsible for + * holding a reference to the file for as long as the socket is in use. */ +struct socket *bf_tun_get_socket(struct file *file) +{ + struct tun_file *tfile; + if (file->f_op != &tun_fops) + return ERR_PTR(-EINVAL); + tfile = file->private_data; + if (!tfile) + return ERR_PTR(-EBADFD); + return &tfile->socket; +} +EXPORT_SYMBOL_GPL(bf_tun_get_socket); + +module_init(tun_init); +module_exit(tun_cleanup); +MODULE_DESCRIPTION(DRV_DESCRIPTION); +MODULE_AUTHOR(DRV_COPYRIGHT); +MODULE_LICENSE("GPL"); +MODULE_ALIAS_MISCDEV(TUN_MINOR1); +MODULE_ALIAS("devname:net/bf_tun"); diff --git a/platform/barefoot/sonic-platform-modules-wnc-osw1800/modules/i2c-mcp2221.c b/platform/barefoot/sonic-platform-modules-wnc-osw1800/modules/i2c-mcp2221.c new file mode 100644 index 000000000000..fcaa57fbafac --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-wnc-osw1800/modules/i2c-mcp2221.c @@ -0,0 +1,611 @@ +/* + * i2c bus driver for MCP2221 + * + * Derived from: + * i2c-tiny-usb.c + * i2c-diolan-u2c.c + * usb-serial.c + * onetouch.c + * usb-skeleton.c + * + * Copyright (C) 2014 Microchip Technology Inc. + * + * Author: Bogdan Bolocan http://www.microchip.com/support + * + * 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. + * + * + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRIVER_NAME "i2c-mcp2221" + +#define USB_VENDOR_ID_MCP2221 0x04d8 +#define USB_DEVICE_ID_MCP2221 0x00dd + +#define MCP2221_OUTBUF_LEN 64 /* USB write packet length */ +#define MCP2221_INBUF_LEN 64 /* USB read packet length */ + +#define MCP2221_MAX_I2C_DATA_LEN 60 + +//#define MCP2221_FREQ_STD 100000 +#define MCP2221_FREQ_STD 400000 +//#define MCP2221_FREQ_STD 50000 +#define MCP2221_FREQ_MAX 500000 + +#define MCP2221_RETRY_MAX 50 +#define MCP2221_STD_DELAY_MS 1 +//#define MCP2221_STD_DELAY_MS 2 + +#define RESP_ERR_NOERR 0x00 +#define RESP_ADDR_NACK 0x25 +#define RESP_READ_ERR 0x7F +#define RESP_READ_COMPL 0x55 +#define RESP_I2C_IDLE 0x00 +#define RESP_I2C_START_TOUT 0x12 +#define RESP_I2C_RSTART_TOUT 0x17 +#define RESP_I2C_WRADDRL_TOUT 0x23 +#define RESP_I2C_WRADDRL_WSEND 0x21 +#define RESP_I2C_WRADDRL_NACK 0x25 +#define RESP_I2C_WRDATA_TOUT 0x44 +#define RESP_I2C_RDDATA_TOUT 0x52 +#define RESP_I2C_STOP_TOUT 0x62 + +#define CMD_MCP2221_STATUS 0x10 +#define SUBCMD_STATUS_CANCEL 0x10 +#define SUBCMD_STATUS_SPEED 0x20 +#define MASK_ADDR_NACK 0x40 + +#define CMD_MCP2221_RDDATA7 0x91 +#define CMD_MCP2221_GET_RDDATA 0x40 + +#define CMD_MCP2221_WRDATA7 0x90 + +/* Structure to hold all of our device specific stuff */ +struct i2c_mcp2221 { + u8 obuffer[MCP2221_OUTBUF_LEN]; /* USB write buffer */ + u8 ibuffer[MCP2221_INBUF_LEN]; /* USB read buffer */ + /* I2C/SMBus data buffer */ + u8 user_data_buffer[MCP2221_MAX_I2C_DATA_LEN]; + int ep_in, ep_out; /* Endpoints */ + struct usb_device *usb_dev; /* the usb device for this device */ + struct usb_interface *interface;/* the interface for this device */ + struct i2c_adapter adapter; /* i2c related things */ + uint frequency; /* I2C/SMBus communication frequency */ + /* Mutex for low-level USB transactions */ + struct mutex mcp2221_usb_op_lock; + /* wq to wait for an ongoing read/write */ + wait_queue_head_t usb_urb_completion_wait; + bool ongoing_usb_ll_op; /* a ll is in progress */ + + struct urb *interrupt_in_urb; + struct urb *interrupt_out_urb; +}; + +static uint frequency = MCP2221_FREQ_STD; /* I2C clock frequency in Hz */ + +module_param(frequency, uint, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(frequency, "I2C clock frequency in hertz"); + +/* usb layer */ + + +/* + * Return list of supported functionality. + */ +static u32 mcp2221_usb_func(struct i2c_adapter *a) +{ + return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | + I2C_FUNC_SMBUS_READ_BLOCK_DATA | I2C_FUNC_SMBUS_BLOCK_PROC_CALL; +} + +static void mcp2221_usb_cmpl_cbk(struct urb *urb) +{ + struct i2c_mcp2221 *dev = urb->context; + int status = urb->status; + int retval; + + switch (status) { + case 0: /* success */ + break; + case -ECONNRESET: /* unlink */ + case -ENOENT: + case -ESHUTDOWN: + return; + /* -EPIPE: should clear the halt */ + default: /* error */ + goto resubmit; + } + + /* wake up the waitting function + modify the flag indicating the ll status */ + dev->ongoing_usb_ll_op = 0; + wake_up_interruptible(&dev->usb_urb_completion_wait); + return; + +resubmit: + retval = usb_submit_urb(urb, GFP_ATOMIC); + if (retval) { + dev_err(&dev->interface->dev, + "mcp2221(irq): can't resubmit intrerrupt urb, retval %d\n", + retval); + } +} + +static int mcp2221_ll_cmd(struct i2c_mcp2221 *dev) +{ + int rv; + + /* tell everybody to leave the URB alone */ + dev->ongoing_usb_ll_op = 1; + + /* submit the interrupt out ep packet */ + if (usb_submit_urb(dev->interrupt_out_urb, GFP_KERNEL)) { + dev_err(&dev->interface->dev, + "mcp2221(ll): usb_submit_urb intr out failed\n"); + dev->ongoing_usb_ll_op = 0; + return -EIO; + } + + /* wait for its completion */ + rv = wait_event_interruptible(dev->usb_urb_completion_wait, + (!dev->ongoing_usb_ll_op)); + if (rv < 0) { + dev_err(&dev->interface->dev, "mcp2221(ll): wait interrupted\n"); + goto ll_exit_clear_flag; + } + + /* tell everybody to leave the URB alone */ + dev->ongoing_usb_ll_op = 1; + + /* submit the interrupt in ep packet */ + if (usb_submit_urb(dev->interrupt_in_urb, GFP_KERNEL)) { + dev_err(&dev->interface->dev, "mcp2221(ll): usb_submit_urb intr in failed\n"); + dev->ongoing_usb_ll_op = 0; + return -EIO; + } + + /* wait for its completion */ + rv = wait_event_interruptible(dev->usb_urb_completion_wait, + (!dev->ongoing_usb_ll_op)); + if (rv < 0) { + dev_err(&dev->interface->dev, "mcp2221(ll): wait interrupted\n"); + goto ll_exit_clear_flag; + } + +ll_exit_clear_flag: + dev->ongoing_usb_ll_op = 0; + return rv; +} + +static int mcp2221_init(struct i2c_mcp2221 *dev) +{ + int ret; + + ret = 0; + if (frequency > MCP2221_FREQ_MAX) + frequency = MCP2221_FREQ_MAX; + + /* initialize the MCP2221 and bring it to "idle/ready" state */ + dev_info(&dev->interface->dev, + "MCP2221 at USB bus %03d address %03d Freq=%dKhz-- mcp2221_init()\n", + dev->usb_dev->bus->busnum, dev->usb_dev->devnum, frequency/1000); + + /* initialize unlocked mutex */ + mutex_init(&dev->mcp2221_usb_op_lock); + + dev->interrupt_out_urb = usb_alloc_urb(0, GFP_KERNEL); + if (!dev->interrupt_out_urb) + goto init_error; + + usb_fill_int_urb(dev->interrupt_out_urb, dev->usb_dev, + usb_sndintpipe(dev->usb_dev, + dev->ep_out), + (void *)&dev->obuffer, MCP2221_OUTBUF_LEN, + mcp2221_usb_cmpl_cbk, dev, + 1); + + dev->interrupt_in_urb = usb_alloc_urb(0, GFP_KERNEL); + if (!dev->interrupt_in_urb) + goto init_error; + + usb_fill_int_urb(dev->interrupt_in_urb, dev->usb_dev, + usb_rcvintpipe(dev->usb_dev, + dev->ep_in), + (void *)&dev->ibuffer, MCP2221_INBUF_LEN, + mcp2221_usb_cmpl_cbk, dev, + 1); + ret = 0; + goto init_no_error; + +init_error: + dev_err(&dev->interface->dev, "mcp2221_init: Error = %d\n", ret); + ret = -ENODEV; + +init_no_error: + dev_info(&dev->interface->dev, "mcp2221_init: Success\n"); + return ret; +} + +static int mcp2221_i2c_readwrite(struct i2c_mcp2221 *dev, + struct i2c_msg *pmsg) +{ + u8 ucI2cDiv, ucCancelXfer, ucXferLen; + int rv, retries; + unsigned int sleepCmd; + u8 *pSrc, *pDst, usbCmdStatus; + + retries = 0; + ucCancelXfer = 0; + /* clock divider for I2C operations */ + ucI2cDiv = (u8)((12000000/frequency) - 3); + + /* determine the best delay value here */ + /* (MCP2221_STD_DELAY_MS * MCP2221_FREQ_MAX)/frequency; */ + sleepCmd = MCP2221_STD_DELAY_MS; + + if (pmsg->len > MCP2221_MAX_I2C_DATA_LEN) + return -EINVAL; + +readwrite_reinit: + dev->obuffer[0] = CMD_MCP2221_STATUS; /* code for STATUS cmd */ + dev->obuffer[1] = 0x00; + dev->obuffer[2] = ucCancelXfer; /* cancel subcmd */ + dev->obuffer[3] = SUBCMD_STATUS_SPEED; /* set the xfer speed */ + dev->obuffer[4] = ucI2cDiv; + dev->obuffer[5] = 0x00; + dev->obuffer[6] = 0x00; + dev->obuffer[7] = 0x00; + + rv = mcp2221_ll_cmd(dev); + if (rv < 0) + return -EFAULT; + + if (dev->ibuffer[1] != RESP_ERR_NOERR) + return -EFAULT; + + if (dev->ibuffer[3] != SUBCMD_STATUS_SPEED) { + /* the speed could not be set - wait a while and retry */ + if (retries < MCP2221_RETRY_MAX) { + /* wait a while and retry the operation */ + retries++; + msleep(MCP2221_STD_DELAY_MS); + ucCancelXfer = SUBCMD_STATUS_CANCEL; + goto readwrite_reinit; + } else { + /* max number of retries was reached - return error */ + dev_err(&dev->interface->dev, + "mcp2221 CANCEL ERROR:retries = %d\n", retries); + return -EFAULT; + } + } + + if (pmsg->flags & I2C_M_RD) { + /* I2C read */ + ucXferLen = (u8)pmsg->len; + dev->obuffer[0] = CMD_MCP2221_RDDATA7; + dev->obuffer[1] = ucXferLen; /* LSB of the xfer length */ + dev->obuffer[2] = 0; /* no MSB for the xfer length */ + /* address in 8-bit format */ + dev->obuffer[3] = (u8)((pmsg->addr) << 1); + + rv = mcp2221_ll_cmd(dev); + if (rv < 0) + return -EFAULT; + + if (dev->ibuffer[1] != RESP_ERR_NOERR) + return -EFAULT; + + retries = 0; + dev->obuffer[0] = CMD_MCP2221_GET_RDDATA; + dev->obuffer[1] = 0x00; + dev->obuffer[2] = 0x00; + dev->obuffer[3] = 0x00; + + while (retries < MCP2221_RETRY_MAX) { + msleep(sleepCmd); + + rv = mcp2221_ll_cmd(dev); + if (rv < 0) + return -EFAULT; + + if (dev->ibuffer[1] != RESP_ERR_NOERR) + return -EFAULT; + + if (dev->ibuffer[2] == RESP_ADDR_NACK) + return -EFAULT; + + /* break the loop - cmd ended ok - used for bus scan */ + if ((dev->ibuffer[3] == 0x00) && + (dev->ibuffer[2] == 0x00)) + break; + + if (dev->ibuffer[3] == RESP_READ_ERR) { + retries++; + continue; + } + + if ((dev->ibuffer[2] == RESP_READ_COMPL) && + (dev->ibuffer[3] == ucXferLen)) { + /* we got the data - copy it */ + pSrc = (u8 *)&dev->ibuffer[4]; + pDst = (u8 *)&pmsg->buf[0]; + memcpy(pDst, pSrc, ucXferLen); + + if (pmsg->flags & I2C_M_RECV_LEN) + pmsg->len = ucXferLen; + + break; + } + + } + if (retries >= MCP2221_RETRY_MAX) + return -EFAULT; + } else { + /* I2C write */ + ucXferLen = (u8)pmsg->len; + dev->obuffer[0] = CMD_MCP2221_WRDATA7; + dev->obuffer[1] = ucXferLen; /* LSB of the xfer length */ + dev->obuffer[2] = 0; /* no MSB for the xfer length */ + /* address in 8-bit format */ + dev->obuffer[3] = (u8)((pmsg->addr) << 1); + /* copy the data we've read back */ + pSrc = (u8 *)&pmsg->buf[0]; + pDst = (u8 *)&dev->obuffer[4]; + memcpy(pDst, pSrc, ucXferLen); + + retries = 0; + + while (retries < MCP2221_RETRY_MAX) { + rv = mcp2221_ll_cmd(dev); + if (rv < 0) + return -EFAULT; + + if (dev->ibuffer[1] != RESP_ERR_NOERR) { + usbCmdStatus = dev->ibuffer[2]; + if (usbCmdStatus == RESP_I2C_START_TOUT) + return -EFAULT; + + if (usbCmdStatus == RESP_I2C_WRADDRL_TOUT) + return -EFAULT; + + if (usbCmdStatus == RESP_I2C_WRADDRL_NACK) + return -EFAULT; + + if (usbCmdStatus == RESP_I2C_WRDATA_TOUT) + return -EFAULT; + + if (usbCmdStatus == RESP_I2C_STOP_TOUT) + return -EFAULT; + + msleep(sleepCmd); + retries++; + continue; + } else { /* command completed successfully */ + break; + } + } + if (retries >= MCP2221_RETRY_MAX) + return -EFAULT; + + /* now, prepare for the STATUS stage */ + retries = 0; + dev->obuffer[0] = CMD_MCP2221_STATUS; /* code for STATUS cmd */ + dev->obuffer[1] = 0x00; + dev->obuffer[2] = 0x00; + dev->obuffer[3] = 0x00; + dev->obuffer[4] = 0x00; + dev->obuffer[5] = 0x00; + dev->obuffer[6] = 0x00; + dev->obuffer[7] = 0x00; + + while (retries < MCP2221_RETRY_MAX) { + rv = mcp2221_ll_cmd(dev); + if (rv < 0) + return -EFAULT; + + if (dev->ibuffer[1] != RESP_ERR_NOERR) + return -EFAULT; + + /* i2c slave address was nack-ed */ + if (dev->ibuffer[20] & MASK_ADDR_NACK) + return -EFAULT; + + usbCmdStatus = dev->ibuffer[8]; + if (usbCmdStatus == RESP_I2C_IDLE) + break; + + if (usbCmdStatus == RESP_I2C_START_TOUT) + return -EFAULT; + + if (usbCmdStatus == RESP_I2C_WRADDRL_TOUT) + return -EFAULT; + + if (usbCmdStatus == RESP_I2C_WRADDRL_WSEND) + return -EFAULT; + + if (usbCmdStatus == RESP_I2C_WRADDRL_NACK) + return -EFAULT; + + if (usbCmdStatus == RESP_I2C_WRDATA_TOUT) + return -EFAULT; + + if (usbCmdStatus == RESP_I2C_STOP_TOUT) + return -EFAULT; + + msleep(sleepCmd); + retries++; + } + if (retries >= MCP2221_RETRY_MAX) + return -EFAULT; + } + + return 0; +} + +/* device layer */ +static int mcp2221_usb_i2c_xfer(struct i2c_adapter *adap, + struct i2c_msg *msgs, int num) +{ + struct i2c_mcp2221 *dev = i2c_get_adapdata(adap); + struct i2c_msg *pmsg; + int ret, count; + + for (count = 0; count < num; count++) { + pmsg = &msgs[count]; + /* no concurrent users of the mcp2221 i2c xfer */ + ret = mutex_lock_interruptible(&dev->mcp2221_usb_op_lock); + if (ret < 0) + goto abort; + + ret = mcp2221_i2c_readwrite(dev, pmsg); + mutex_unlock(&dev->mcp2221_usb_op_lock); + if (ret < 0) + goto abort; + } + + /* if all the messages were transferred ok, return "num" */ + ret = num; + +abort: + return ret; +} + +static const struct i2c_algorithm mcp2221_usb_algorithm = { + .master_xfer = mcp2221_usb_i2c_xfer, + .functionality = mcp2221_usb_func, +}; + +static const struct usb_device_id mcp2221_table[] = { + { USB_DEVICE(USB_VENDOR_ID_MCP2221, USB_DEVICE_ID_MCP2221) }, + { } +}; + +MODULE_DEVICE_TABLE(usb, mcp2221_table); + +static void mcp2221_free(struct i2c_mcp2221 *dev) +{ + usb_put_dev(dev->usb_dev); + kfree(dev); +} + +static int mcp2221_probe(struct usb_interface *interface, + const struct usb_device_id *id) +{ + struct usb_host_interface *hostif = interface->cur_altsetting; + struct i2c_mcp2221 *dev; + int ret; + + if ((hostif->desc.bInterfaceNumber != 2) + || (hostif->desc.bInterfaceClass != 3)) { + pr_info("i2c-mcp2221(probe): Interface doesn't match the MCP2221 HID\n"); + return -ENODEV; + } + + /* allocate memory for our device state and initialize it */ + dev = kzalloc(sizeof(*dev), GFP_KERNEL); + if (dev == NULL) { + pr_info("i2c-mcp2221(probe): no memory for device state\n"); + ret = -ENOMEM; + goto error; + } + + dev->ep_in = hostif->endpoint[0].desc.bEndpointAddress; + dev->ep_out = hostif->endpoint[1].desc.bEndpointAddress; + + dev->usb_dev = usb_get_dev(interface_to_usbdev(interface)); + dev->interface = interface; + + init_waitqueue_head(&dev->usb_urb_completion_wait); + + /* save our data pointer in this interface device */ + usb_set_intfdata(interface, dev); + + /* setup i2c adapter description */ + dev->adapter.owner = THIS_MODULE; + dev->adapter.class = I2C_CLASS_HWMON; + dev->adapter.algo = &mcp2221_usb_algorithm; + i2c_set_adapdata(&dev->adapter, dev); + + snprintf(dev->adapter.name, sizeof(dev->adapter.name), + DRIVER_NAME " at bus %03d device %03d", + dev->usb_dev->bus->busnum, dev->usb_dev->devnum); + + dev->adapter.dev.parent = &dev->interface->dev; + + /* initialize mcp2221 i2c interface */ + ret = mcp2221_init(dev); + if (ret < 0) { + dev_err(&interface->dev, "failed to initialize adapter\n"); + goto error_free; + } + + /* and finally attach to i2c layer */ + ret = i2c_add_adapter(&dev->adapter); + if (ret < 0) { + dev_err(&interface->dev, "failed to add I2C adapter\n"); + goto error_free; + } + + dev_info(&dev->interface->dev, + "mcp2221_probe() -> chip connected -> Success\n"); + return 0; + +error_free: + usb_set_intfdata(interface, NULL); + mcp2221_free(dev); +error: + return ret; +} + +static void mcp2221_disconnect(struct usb_interface *interface) +{ + struct i2c_mcp2221 *dev = usb_get_intfdata(interface); + + i2c_del_adapter(&dev->adapter); + + usb_kill_urb(dev->interrupt_in_urb); + usb_kill_urb(dev->interrupt_out_urb); + usb_free_urb(dev->interrupt_in_urb); + usb_free_urb(dev->interrupt_out_urb); + + usb_set_intfdata(interface, NULL); + mcp2221_free(dev); + + pr_info("i2c-mcp2221(disconnect) -> chip disconnected"); +} + +static struct usb_driver mcp2221_driver = { + .name = DRIVER_NAME, + .probe = mcp2221_probe, + .disconnect = mcp2221_disconnect, + .id_table = mcp2221_table, +}; + +module_usb_driver(mcp2221_driver); + +MODULE_AUTHOR("Bogdan Bolocan"); +MODULE_DESCRIPTION(DRIVER_NAME "I2C MCP2221"); +MODULE_LICENSE("GPL v2"); diff --git a/platform/barefoot/sonic-platform-modules-wnc-osw1800/modules/wnc_cpld.c b/platform/barefoot/sonic-platform-modules-wnc-osw1800/modules/wnc_cpld.c new file mode 100644 index 000000000000..3a7d40ba9177 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-wnc-osw1800/modules/wnc_cpld.c @@ -0,0 +1,198 @@ +/* + * wnc_cpld.c - A driver for control wnc_cpld base on lm75.c + * + * Copyright (c) 1998, 1999 Frodo Looijaard + * Copyright (c) 2017 WNC + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Addresses scanned */ +static const unsigned short normal_i2c[] = { 0x31, 0x32, I2C_CLIENT_END }; + +/* Size of EEPROM in bytes */ +#define CPLD_SIZE 3 + +/* Each client has this additional data */ +struct cpld_data { + struct mutex update_lock; + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 data[CPLD_SIZE]; /* Register value */ +}; + +static ssize_t show_value(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 cpld_data *data = i2c_get_clientdata(client); + + mutex_lock(&data->update_lock); + data->data[0] = i2c_smbus_read_byte_data(client, attr->index); + mutex_unlock(&data->update_lock); + + return sprintf(buf, "%02x\n", data->data[0]); +} + +static ssize_t set_value(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 cpld_data *data = i2c_get_clientdata(client); + u8 temp; + int error; + + error = kstrtou8(buf, 10, &temp); + if (error) + return error; + + mutex_lock(&data->update_lock); + i2c_smbus_write_byte_data(client, attr->index, temp); + mutex_unlock(&data->update_lock); + + return count; +} + +static SENSOR_DEVICE_ATTR(reset_control, S_IWUSR | S_IRUGO, show_value, set_value, 2); +static SENSOR_DEVICE_ATTR(sfp_mod_abs1, S_IRUGO, show_value, NULL, 3); +static SENSOR_DEVICE_ATTR(sfp_mod_abs2, S_IRUGO, show_value, NULL, 4); +static SENSOR_DEVICE_ATTR(sfp_mod_abs3, S_IRUGO, show_value, NULL, 5); +static SENSOR_DEVICE_ATTR(sfp_mod_abs4, S_IRUGO, show_value, NULL, 6); +static SENSOR_DEVICE_ATTR(qsfp_modprs, S_IRUGO, show_value, NULL, 22); +static SENSOR_DEVICE_ATTR(qsfp_lpmode, S_IWUSR | S_IRUGO, show_value, set_value, 24); + +static struct attribute *cpld2_attributes[] = { + &sensor_dev_attr_reset_control.dev_attr.attr, + &sensor_dev_attr_sfp_mod_abs1.dev_attr.attr, + &sensor_dev_attr_sfp_mod_abs2.dev_attr.attr, + &sensor_dev_attr_sfp_mod_abs3.dev_attr.attr, + &sensor_dev_attr_qsfp_modprs.dev_attr.attr, + &sensor_dev_attr_qsfp_lpmode.dev_attr.attr, + NULL +}; + +static struct attribute *cpld1_attributes[] = { + &sensor_dev_attr_sfp_mod_abs1.dev_attr.attr, + &sensor_dev_attr_sfp_mod_abs2.dev_attr.attr, + &sensor_dev_attr_sfp_mod_abs3.dev_attr.attr, + &sensor_dev_attr_sfp_mod_abs4.dev_attr.attr, + NULL +}; + +static const struct attribute_group cpld2_group = { + .attrs = cpld2_attributes, +}; + +static const struct attribute_group cpld1_group = { + .attrs = cpld1_attributes, +}; + +/* Return 0 if detection is successful, -ENODEV otherwise */ +static int cpld_detect(struct i2c_client *new_client, struct i2c_board_info *info) +{ + struct i2c_adapter *adapter = new_client->adapter; + int conf; + + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA | + I2C_FUNC_SMBUS_WORD_DATA)) + return -ENODEV; + + /* Unused bits */ + conf = i2c_smbus_read_byte_data(new_client, 0); + if (!conf) + return -ENODEV; + + return 0; +} + + +static int cpld_probe(struct i2c_client *client, const struct i2c_device_id *id) +{ + struct cpld_data *data; + int status; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) + return -EIO; +#if 1 + data = devm_kzalloc(&client->dev, sizeof(struct cpld_data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); +#endif + + if (client->addr == 49) /* 0x31 */ + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &cpld1_group); + else if (client->addr == 50) /* 0x32 */ + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &cpld2_group); + else + status = 1; + + if (status) + return status; + + dev_info(&client->dev, "cpld 0x%x found\n", client->addr); + + return 0; +} + +static int cpld_remove(struct i2c_client *client) +{ + if (client->addr == 49) /* 0x31 */ + sysfs_remove_group(&client->dev.kobj, &cpld1_group); + else if (client->addr == 50) /* 0x32 */ + sysfs_remove_group(&client->dev.kobj, &cpld2_group); + else + return 1; + + return 0; +} + +static const struct i2c_device_id cpld_id[] = { + { "wnc_cpld", 0 }, + {} +}; +MODULE_DEVICE_TABLE(i2c, cpld_id); + +static struct i2c_driver cpld_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "wnc_cpld", + }, + .probe = cpld_probe, + .remove = cpld_remove, + .id_table = cpld_id, + .detect = cpld_detect, + .address_list = normal_i2c, +}; + +module_i2c_driver(cpld_driver); + +MODULE_AUTHOR("WNC "); +MODULE_DESCRIPTION("WNC CPLD driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/barefoot/sonic-platform-modules-wnc-osw1800/modules/wnc_cpld3.c b/platform/barefoot/sonic-platform-modules-wnc-osw1800/modules/wnc_cpld3.c new file mode 100644 index 000000000000..a24698aa9cef --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-wnc-osw1800/modules/wnc_cpld3.c @@ -0,0 +1,200 @@ +/* + * wnc_cpld.c - A driver for control wnc_cpld3 base on lm75.c + * + * Copyright (c) 1998, 1999 Frodo Looijaard + * Copyright (c) 2017 WNC + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Addresses scanned */ +static const unsigned short normal_i2c[] = { 0x33, I2C_CLIENT_END }; + +/* Size of EEPROM in bytes */ +#define CPLD_SIZE 3 + +/* Each client has this additional data */ +struct cpld_data { + struct i2c_client *client; + struct mutex update_lock; + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 data[CPLD_SIZE]; /* Register value */ +}; + +static ssize_t show_hwmon_value(struct device *dev, struct device_attribute *da, char *buf) +{ + struct cpld_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; + int index = to_sensor_dev_attr_2(da)->index; + + mutex_lock(&data->update_lock); + data->data[0] = i2c_smbus_read_byte_data(client, index); + mutex_unlock(&data->update_lock); + + return sprintf(buf, "%d\n", data->data[0]); +} + +static ssize_t show_sysfs_value(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 cpld_data *data = i2c_get_clientdata(client); + + mutex_lock(&data->update_lock); + data->data[0] = i2c_smbus_read_byte_data(client, attr->index); + mutex_unlock(&data->update_lock); + + return sprintf(buf, "%02x\n", data->data[0]); +} + +static ssize_t set_hwmon_value(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + struct cpld_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; + int index = to_sensor_dev_attr_2(da)->index; + u8 temp; + int error; + + error = kstrtou8(buf, 10, &temp); + if (error) + return error; + + mutex_lock(&data->update_lock); + i2c_smbus_write_byte_data(client, index, temp); + mutex_unlock(&data->update_lock); + + return count; +} + +static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_hwmon_value, NULL, 6); +static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, show_hwmon_value, NULL, 7); +static SENSOR_DEVICE_ATTR(fan3_input, S_IRUGO, show_hwmon_value, NULL, 8); +static SENSOR_DEVICE_ATTR(fan4_input, S_IRUGO, show_hwmon_value, NULL, 9); +static SENSOR_DEVICE_ATTR(fan5_input, S_IRUGO, show_hwmon_value, NULL, 10); +static SENSOR_DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, show_hwmon_value, set_hwmon_value, 6); +static SENSOR_DEVICE_ATTR(pwm2, S_IWUSR | S_IRUGO, show_hwmon_value, set_hwmon_value, 7); +static SENSOR_DEVICE_ATTR(pwm3, S_IWUSR | S_IRUGO, show_hwmon_value, set_hwmon_value, 8); +static SENSOR_DEVICE_ATTR(pwm4, S_IWUSR | S_IRUGO, show_hwmon_value, set_hwmon_value, 9); +static SENSOR_DEVICE_ATTR(pwm5, S_IWUSR | S_IRUGO, show_hwmon_value, set_hwmon_value, 10); + +static struct attribute *cpld3_hwmon_attrs[] = { + &sensor_dev_attr_fan1_input.dev_attr.attr, + &sensor_dev_attr_fan2_input.dev_attr.attr, + &sensor_dev_attr_fan3_input.dev_attr.attr, + &sensor_dev_attr_fan4_input.dev_attr.attr, + &sensor_dev_attr_fan5_input.dev_attr.attr, + &sensor_dev_attr_pwm1.dev_attr.attr, + &sensor_dev_attr_pwm2.dev_attr.attr, + &sensor_dev_attr_pwm3.dev_attr.attr, + &sensor_dev_attr_pwm4.dev_attr.attr, + &sensor_dev_attr_pwm5.dev_attr.attr, + NULL +}; + +ATTRIBUTE_GROUPS(cpld3_hwmon); + +static SENSOR_DEVICE_ATTR(cpld_version, S_IRUGO, show_sysfs_value, NULL, 1); +static SENSOR_DEVICE_ATTR(power_good, S_IRUGO, show_sysfs_value, NULL, 4); + +static struct attribute *cpld3_sysfs_attrs[] = { + &sensor_dev_attr_cpld_version.dev_attr.attr, + &sensor_dev_attr_power_good.dev_attr.attr, + NULL +}; + +static const struct attribute_group cpld3_sysfs_group = { + .attrs = cpld3_sysfs_attrs, +}; + +/* Return 0 if detection is successful, -ENODEV otherwise */ +static int cpld_detect(struct i2c_client *new_client, struct i2c_board_info *info) +{ + struct i2c_adapter *adapter = new_client->adapter; + int conf; + + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA | + I2C_FUNC_SMBUS_WORD_DATA)) + return -ENODEV; + + /* Unused bits */ + conf = i2c_smbus_read_byte_data(new_client, 0); + if (!conf) + return -ENODEV; + + return 0; +} + + +static int cpld_probe(struct i2c_client *client, const struct i2c_device_id *id) +{ + struct device *hwmon_dev; + struct cpld_data *data; + int status; + + data = devm_kzalloc(&client->dev, sizeof(struct cpld_data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + data->client = client; + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); + + status = sysfs_create_group(&client->dev.kobj, &cpld3_sysfs_group); + hwmon_dev = devm_hwmon_device_register_with_groups(&client->dev, client->name, data, cpld3_hwmon_groups); + + return PTR_ERR_OR_ZERO(hwmon_dev); +} + +static int cpld_remove(struct i2c_client *client) +{ + devm_hwmon_device_unregister(&client->dev); + sysfs_remove_group(&client->dev.kobj, &cpld3_sysfs_group); + return 0; +} + +static const struct i2c_device_id cpld_id[] = { + { "wnc_cpld3", 0 }, + {} +}; +MODULE_DEVICE_TABLE(i2c, cpld_id); + +static struct i2c_driver cpld_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "wnc_cpld3", + }, + .probe = cpld_probe, + .remove = cpld_remove, + .id_table = cpld_id, + .detect = cpld_detect, + .address_list = normal_i2c, +}; + +module_i2c_driver(cpld_driver); + +MODULE_AUTHOR("WNC "); +MODULE_DESCRIPTION("WNC CPLD3 driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/barefoot/sonic-platform-modules-wnc-osw1800/modules/wnc_eeprom.c b/platform/barefoot/sonic-platform-modules-wnc-osw1800/modules/wnc_eeprom.c new file mode 100644 index 000000000000..8ddf1f2af279 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-wnc-osw1800/modules/wnc_eeprom.c @@ -0,0 +1,286 @@ +/* + * Copyright (C) 1998, 1999 Frodo Looijaard and + * Philip Edelbrock + * Copyright (C) 2003 Greg Kroah-Hartman + * Copyright (C) 2003 IBM Corp. + * Copyright (C) 2004 Jean Delvare + * + * 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. + */ + +#include +#include +#include +#include +#include +#include + +/* Addresses to scan */ +static const unsigned short normal_i2c[] = { 0x50, 0x51, 0x52, 0x53, 0x54, + 0x55, 0x56, 0x57, I2C_CLIENT_END }; + + +/* Size of EEPROM in bytes */ +#define EEPROM_SIZE 256 + +/* possible types of eeprom devices */ +enum eeprom_nature { + UNKNOWN, + VAIO, +}; + +/* Each client has this additional data */ +struct eeprom_data { + struct mutex update_lock; + u8 valid; /* bitfield, bit!=0 if slice is valid */ + unsigned long last_updated[8]; /* In jiffies, 8 slices */ + u8 data[EEPROM_SIZE]; /* Register values */ + enum eeprom_nature nature; +}; + + +static void eeprom_update_client(struct i2c_client *client, u8 slice) +{ + struct eeprom_data *data = i2c_get_clientdata(client); + int i; + + mutex_lock(&data->update_lock); + + if (!(data->valid & (1 << slice)) || + time_after(jiffies, data->last_updated[slice] + 300 * HZ)) { + dev_dbg(&client->dev, "Starting eeprom update, slice %u\n", slice); + + if (i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_READ_I2C_BLOCK)) { + //for (i = slice << 5; i < (slice + 1) << 5; i += 32) + for (i = slice << 5; i < (slice + 1) << 5; i += 24) + if (i2c_smbus_read_i2c_block_data(client, i, + 24, data->data + i) + != 24) + goto exit; + } else { + for (i = slice << 5; i < (slice + 1) << 5; i += 2) { + int word = i2c_smbus_read_word_data(client, i); + if (word < 0) + goto exit; + data->data[i] = word & 0xff; + data->data[i + 1] = word >> 8; + } + } + data->last_updated[slice] = jiffies; + data->valid |= (1 << slice); + } +exit: + mutex_unlock(&data->update_lock); +} + +static ssize_t eeprom_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buf, loff_t off, size_t count) +{ + struct i2c_client *client = to_i2c_client(container_of(kobj, struct device, kobj)); + struct eeprom_data *data = i2c_get_clientdata(client); + u8 slice; + + data->valid = 0; + + if (off > EEPROM_SIZE) + return 0; + if (off + count > EEPROM_SIZE) + count = EEPROM_SIZE - off; + + /* Only refresh slices which contain requested bytes */ + for (slice = off >> 5; slice <= (off + count - 1) >> 5; slice++) + eeprom_update_client(client, slice); + + /* Hide Vaio private settings to regular users: + - BIOS passwords: bytes 0x00 to 0x0f + - UUID: bytes 0x10 to 0x1f + - Serial number: 0xc0 to 0xdf */ + if (data->nature == VAIO && !capable(CAP_SYS_ADMIN)) { + int i; + + for (i = 0; i < count; i++) { + if ((off + i <= 0x1f) || + (off + i >= 0xc0 && off + i <= 0xdf)) + buf[i] = 0; + else + buf[i] = data->data[off + i]; + } + } else { + memcpy(buf, &data->data[off], count); + } + + return count; +} + +static ssize_t eeprom_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buf, loff_t off, size_t count) +{ + struct i2c_client *client = to_i2c_client(container_of(kobj, struct device, kobj)); + struct eeprom_data *data = i2c_get_clientdata(client); + u8 temp; + int error, reg; + + mutex_lock(&data->update_lock); + + error = kstrtou8(buf, 10, &temp); + if (error) + return error; + + if (client->addr == 0x51) { /* SFP AOC cable, page selection byte is 126 */ + reg = 126; + } + else if (client->addr == 0x50) { /* QSFP, page selection byte is 127 */ + data->data[0] = i2c_smbus_read_byte_data(client, 0); + + /* Base on SFF-8024, determine this module is SFP or QSFP by byte 0 (Identifier) */ + switch (data->data[0]){ + case 12: + case 13: + case 17: + case 24: + reg = 127; + break; + + default: + goto exit; + } + } + else + goto exit; + + i2c_smbus_write_byte_data(client, reg, temp); + +exit: + mutex_unlock(&data->update_lock); + + return count; +} + +static struct bin_attribute eeprom_attr = { + .attr = { + .name = "eeprom", + .mode = S_IWUSR | S_IRUGO | S_IWGRP | S_IWOTH, + }, + .size = EEPROM_SIZE, + .read = eeprom_read, + .write = eeprom_write, +}; + +/* Return 0 if detection is successful, -ENODEV otherwise */ +static int eeprom_detect(struct i2c_client *client, struct i2c_board_info *info) +{ + struct i2c_adapter *adapter = client->adapter; + + /* EDID EEPROMs are often 24C00 EEPROMs, which answer to all + addresses 0x50-0x57, but we only care about 0x50. So decline + attaching to addresses >= 0x51 on DDC buses */ + if (!(adapter->class & I2C_CLASS_SPD) && client->addr >= 0x51) + return -ENODEV; + + /* There are four ways we can read the EEPROM data: + (1) I2C block reads (faster, but unsupported by most adapters) + (2) Word reads (128% overhead) + (3) Consecutive byte reads (88% overhead, unsafe) + (4) Regular byte data reads (265% overhead) + The third and fourth methods are not implemented by this driver + because all known adapters support one of the first two. */ + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_WORD_DATA) + && !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_I2C_BLOCK)) + return -ENODEV; + + strlcpy(info->type, "wnc_eeprom", I2C_NAME_SIZE); + + return 0; +} + +static int eeprom_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct i2c_adapter *adapter = client->adapter; + struct eeprom_data *data; + int err; + + if (!(data = kzalloc(sizeof(struct eeprom_data), GFP_KERNEL))) { + err = -ENOMEM; + goto exit; + } + + memset(data->data, 0xff, EEPROM_SIZE); + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); + data->nature = UNKNOWN; + + /* Detect the Vaio nature of EEPROMs. + We use the "PCG-" or "VGN-" prefix as the signature. */ + if (client->addr == 0x57 + && i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_BYTE_DATA)) { + char name[4]; + + name[0] = i2c_smbus_read_byte_data(client, 0x80); + name[1] = i2c_smbus_read_byte_data(client, 0x81); + name[2] = i2c_smbus_read_byte_data(client, 0x82); + name[3] = i2c_smbus_read_byte_data(client, 0x83); + + if (!memcmp(name, "PCG-", 4) || !memcmp(name, "VGN-", 4)) { + dev_info(&client->dev, "Vaio EEPROM detected, " + "enabling privacy protection\n"); + data->nature = VAIO; + } + } + + /* create the sysfs eeprom file */ + err = sysfs_create_bin_file(&client->dev.kobj, &eeprom_attr); + if (err) + goto exit_kfree; + + return 0; + +exit_kfree: + kfree(data); +exit: + return err; +} + +static int eeprom_remove(struct i2c_client *client) +{ + sysfs_remove_bin_file(&client->dev.kobj, &eeprom_attr); + kfree(i2c_get_clientdata(client)); + + return 0; +} + +static const struct i2c_device_id eeprom_id[] = { + { "wnc_eeprom", 0 }, + { } +}; + +static struct i2c_driver eeprom_driver = { + .driver = { + .name = "wnc_eeprom", + }, + .probe = eeprom_probe, + .remove = eeprom_remove, + .id_table = eeprom_id, + + .class = I2C_CLASS_DDC | I2C_CLASS_SPD, + .detect = eeprom_detect, + .address_list = normal_i2c, +}; + +module_i2c_driver(eeprom_driver); + +MODULE_AUTHOR("Frodo Looijaard and " + "Philip Edelbrock and " + "Greg Kroah-Hartman "); +MODULE_DESCRIPTION("I2C EEPROM driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/barefoot/sonic-platform-modules-wnc-osw1800/scripts/device_node.sh b/platform/barefoot/sonic-platform-modules-wnc-osw1800/scripts/device_node.sh new file mode 100644 index 000000000000..7e1c7c45a725 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-wnc-osw1800/scripts/device_node.sh @@ -0,0 +1,91 @@ +#!/bin/bash + +SEARCH_I2C_BUS=$(ls /sys/bus/i2c/devices) +I2C_BUS=-1 + +for i in $SEARCH_I2C_BUS +do + if [[ -n $(cat /sys/bus/i2c/devices/$i/name | grep i2c-mcp2221) ]]; then + I2C_BUS=$(echo $i | sed 's/i2c-//g') + break + fi +done + +if [[ $I2C_BUS == -1 ]]; then + echo "Can't find i2c-mcp2221" + exit +fi + +TOTAL_MUX=8 +START_NODE_NUM=$((I2C_BUS+1)) + +modprobe i2c_mux_pca954x force_deselect_on_exit=1 + +echo pca9548 0x70 > /sys/bus/i2c/devices/i2c-$I2C_BUS/new_device +echo pca9548 0x71 > /sys/bus/i2c/devices/i2c-$I2C_BUS/new_device +echo pca9548 0x72 > /sys/bus/i2c/devices/i2c-$I2C_BUS/new_device +echo pca9548 0x73 > /sys/bus/i2c/devices/i2c-$I2C_BUS/new_device +echo pca9548 0x74 > /sys/bus/i2c/devices/i2c-$I2C_BUS/new_device +echo pca9548 0x75 > /sys/bus/i2c/devices/i2c-$I2C_BUS/new_device +echo pca9548 0x76 > /sys/bus/i2c/devices/i2c-$I2C_BUS/new_device +echo pca9548 0x77 > /sys/bus/i2c/devices/i2c-$I2C_BUS/new_device + +sleep 5 + +/sbin/modprobe wnc_cpld +/sbin/modprobe wnc_cpld3 +/sbin/modprobe wnc_eeprom +/sbin/modprobe eeprom + +# MUX0: i2c-3~i2c-10 +# MUX1: i2c-11~i2c-18 +# MUX2: i2c-19~i2c-26 +# MUX3: i2c-27~i2c-34 +# MUX4: i2c-35~i2c-42 +# MUX5: i2c-43~i2c-50 +# MUX6: i2c-51~i2c-58 +# MUX7: i2c-59~i2c-66 + +# MUX0 channel0 +CHANNEL=0 +echo wnc_cpld 0x31 > /sys/bus/i2c/devices/i2c-$(($START_NODE_NUM+$CHANNEL))/new_device + +# MUX0 channel1 +CHANNEL=1 +echo wnc_cpld 0x32 > /sys/bus/i2c/devices/i2c-$(($START_NODE_NUM+$CHANNEL))/new_device + +# MUX0 channel2 +CHANNEL=2 +echo wnc_cpld3 0x33 > /sys/bus/i2c/devices/i2c-$(($START_NODE_NUM+$CHANNEL))/new_device +echo wnc_eeprom 0x53 > /sys/bus/i2c/devices/i2c-$(($START_NODE_NUM+$CHANNEL))/new_device + +# MUX0 channel3 +CHANNEL=3 +echo wnc_eeprom 0x50 > /sys/bus/i2c/devices/i2c-$(($START_NODE_NUM+$CHANNEL))/new_device +echo wnc_eeprom 0x51 > /sys/bus/i2c/devices/i2c-$(($START_NODE_NUM+$CHANNEL))/new_device + +# MUX0 channel4 +CHANNEL=4 +echo wnc_eeprom 0x54 > /sys/bus/i2c/devices/i2c-$(($START_NODE_NUM+$CHANNEL))/new_device +echo tmp421 0x1E > /sys/bus/i2c/devices/i2c-$(($START_NODE_NUM+$CHANNEL))/new_device +sleep 1 +echo tmp75 0x4E > /sys/bus/i2c/devices/i2c-$(($START_NODE_NUM+$CHANNEL))/new_device +sleep 1 +echo tmp421 0x4F > /sys/bus/i2c/devices/i2c-$(($START_NODE_NUM+$CHANNEL))/new_device + +# MUX0 channel5 +CHANNEL=5 +echo wnc_eeprom 0x52 > /sys/bus/i2c/devices/i2c-$(($START_NODE_NUM+$CHANNEL))/new_device + +# MUX0 channel7 +CHANNEL=7 +#echo wnc_eeprom 0x5B > /sys/bus/i2c/devices/i2c-$(($START_NODE_NUM+$CHANNEL))/new_device + +START_PORT_NUM=$((START_NODE_NUM+8)) +END_PORT_NUM=$((TOTAL_MUX*8+1)) + +for i in $(seq $START_PORT_NUM $END_PORT_NUM) +do + echo wnc_eeprom 0x50 > /sys/bus/i2c/devices/i2c-$i/new_device + echo wnc_eeprom 0x51 > /sys/bus/i2c/devices/i2c-$i/new_device +done diff --git a/platform/barefoot/sonic-platform-modules-wnc-osw1800/scripts/driver_load.sh b/platform/barefoot/sonic-platform-modules-wnc-osw1800/scripts/driver_load.sh new file mode 100644 index 000000000000..81cee0383ff2 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-wnc-osw1800/scripts/driver_load.sh @@ -0,0 +1,50 @@ +#!/bin/bash + +vid=04d8 +pid=00dd + +#check to see if sysfs is mounted +sysfs_path=`awk '/^sysfs/{ print $2 }' < /proc/mounts` +curr_path=`pwd` + +#if variable is empty, we should exit. No SYSFS found +if [[ -z $sysfs_path ]]; then + echo "No sysfs in this system! Exiting..." + exit 1 +fi + +function load_drivers +{ + modprobe i2c-dev + if [[ $? -ne 0 ]]; then + echo "Cannot load the \"i2c-dev\" driver! Exiting..." + exit 1 + fi + modprobe i2c-mcp2221 + if [[ $? -ne 0 ]]; then + echo "Cannot load the \"i2c-mcp2221\" driver! Exiting..." + exit 1 + fi + echo "I2C related drivers are loaded" +} + +usb_device_path=${sysfs_path}/bus/usb/devices + +cd $usb_device_path + +for usbdev in *; do + idvendor=${usb_device_path}/${usbdev}/idVendor + idproduct=${usb_device_path}/${usbdev}/idProduct + usb_driver=${usb_device_path}/${usbdev}/${usbdev}:1.2/driver + if [[ -f $idvendor ]]; then + dev_vid=`grep -i $vid < $idvendor` + dev_pid=`grep -i $pid < $idproduct` + if [[ -n $dev_vid ]] && [[ -n $dev_pid ]]; then + echo "I found the requested VID/PID: $dev_vid, $dev_pid" + load_drivers + echo -n "${usbdev}:1.2" > ${usb_driver}/unbind + echo -n "${usbdev}:1.2" > ${sysfs_path}/bus/usb/drivers/i2c-mcp2221/bind + fi + fi +done + diff --git a/platform/barefoot/sonic-platform-modules-wnc-osw1800/scripts/test b/platform/barefoot/sonic-platform-modules-wnc-osw1800/scripts/test new file mode 100644 index 000000000000..38327722c91f --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-wnc-osw1800/scripts/test @@ -0,0 +1 @@ +echo "test" diff --git a/platform/barefoot/sonic-platform-modules-wnc-osw1800/service/device_node.service b/platform/barefoot/sonic-platform-modules-wnc-osw1800/service/device_node.service new file mode 100644 index 000000000000..fd1bd9b15648 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-wnc-osw1800/service/device_node.service @@ -0,0 +1,11 @@ +[Unit] +Description=Create device nodes for i2c devices. +Requires=driver_load.service +After=driver_load.service + +[Service] +Type=oneshot +ExecStart=/bin/bash /usr/local/bin/device_node.sh + +[Install] +WantedBy=multi-user.target diff --git a/platform/barefoot/sonic-platform-modules-wnc-osw1800/service/driver_load.service b/platform/barefoot/sonic-platform-modules-wnc-osw1800/service/driver_load.service new file mode 100644 index 000000000000..52ce4d2f4442 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-wnc-osw1800/service/driver_load.service @@ -0,0 +1,10 @@ +[Unit] +Description=Initialize i2c-mcp2221 driver. +Before=pmon.service + +[Service] +Type=oneshot +ExecStart=/bin/bash /usr/local/bin/driver_load.sh + +[Install] +WantedBy=multi-user.target From 786a85dcfb9ccade69a66ecbe0a5278f5910dc47 Mon Sep 17 00:00:00 2001 From: Brand Date: Thu, 1 Feb 2018 11:17:01 +0800 Subject: [PATCH 32/58] Modify for Barefoot suggest --- platform/barefoot/bfn-platform-wnc.mk | 5 +++++ platform/barefoot/bfn-platform.mk | 3 ++- platform/barefoot/bfn-sai.mk | 3 ++- platform/barefoot/one-image.mk | 4 ++-- platform/barefoot/rules.mk | 5 +++-- 5 files changed, 14 insertions(+), 6 deletions(-) create mode 100644 platform/barefoot/bfn-platform-wnc.mk diff --git a/platform/barefoot/bfn-platform-wnc.mk b/platform/barefoot/bfn-platform-wnc.mk new file mode 100644 index 000000000000..57ef0e14211b --- /dev/null +++ b/platform/barefoot/bfn-platform-wnc.mk @@ -0,0 +1,5 @@ +BFN_PLATFORM = bfnplatformwnc_1.0.0_amd64.deb +$(BFN_PLATFORM)_URL = "https://github.com/YaoTien/download/raw/master/sonic/sde/7_0_0_18/bfnplatformwnc_1.0.0_amd64.deb" + +SONIC_ONLINE_DEBS += $(BFN_WNC_PLATFORM) # $(BFN_SAI_DEV) +$(BFN_SAI_DEV)_DEPENDS += $(BFN_WNC_PLATFORM) diff --git a/platform/barefoot/bfn-platform.mk b/platform/barefoot/bfn-platform.mk index b5c67a3fd3a8..0851626880be 100644 --- a/platform/barefoot/bfn-platform.mk +++ b/platform/barefoot/bfn-platform.mk @@ -1,5 +1,6 @@ BFN_PLATFORM = bfnplatform_1.0.0_amd64.deb -$(BFN_PLATFORM)_URL = "https://github.com/YaoTien/download/blob/master/sonic/sde/7_0_0_18/bfnplatform_1.0.0_amd64.deb" +#$(BFN_PLATFORM)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/rel_7_0/bfnplatform_1.0.0_amd64.deb" +$(BFN_PLATFORM)_URL = "https://github.com/YaoTien/download/raw/master/sonic/sde/7_0_0_18/bfnplatform_1.0.0_amd64.deb" SONIC_ONLINE_DEBS += $(BFN_PLATFORM) # $(BFN_SAI_DEV) $(BFN_SAI_DEV)_DEPENDS += $(BFN_PLATFORM) diff --git a/platform/barefoot/bfn-sai.mk b/platform/barefoot/bfn-sai.mk index 28abac7e9093..87b374d3a3aa 100644 --- a/platform/barefoot/bfn-sai.mk +++ b/platform/barefoot/bfn-sai.mk @@ -1,5 +1,6 @@ BFN_SAI = bfnsdk_1.0.0_amd64.deb -$(BFN_SAI)_URL = "https://github.com/YaoTien/download/blob/master/sonic/sde/7_0_0_18/bfnsdk_1.0.0_amd64.deb" +#$(BFN_SAI)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/rel_7_0/bfnsdk_1.0.0_amd64.deb" +$(BFN_SAI)_URL = "https://github.com/YaoTien/download/raw/master/sonic/sde/7_0_0_18/bfnsdk_1.0.0_amd64.deb" # $(BFN_SAI_DEV)_URL = "https://www.dropbox.com/s/4ljk6hzw82rudsr/bfnsdk_1.0.0_amd64.deb?dl=0" SONIC_ONLINE_DEBS += $(BFN_SAI) # $(BFN_SAI_DEV) diff --git a/platform/barefoot/one-image.mk b/platform/barefoot/one-image.mk index b6dc08aa9671..8dc12e9fa8ca 100644 --- a/platform/barefoot/one-image.mk +++ b/platform/barefoot/one-image.mk @@ -3,8 +3,8 @@ SONIC_ONE_IMAGE = sonic-barefoot.bin $(SONIC_ONE_IMAGE)_MACHINE = barefoot $(SONIC_ONE_IMAGE)_IMAGE_TYPE = onie -#$(SONIC_ONE_IMAGE)_INSTALLS += $(BFN_PLATFORM_MODULE) -#$(SONIC_ONE_IMAGE)_INSTALLS += $(BFN_MONTARA_PLATFORM_MODULE) +$(SONIC_ONE_IMAGE)_INSTALLS += $(BFN_PLATFORM_MODULE) +$(SONIC_ONE_IMAGE)_INSTALLS += $(BFN_MONTARA_PLATFORM_MODULE) $(SONIC_ONE_IMAGE)_INSTALLS += $(WNC_OSW1800_PLATFORM_MODULE) $(SONIC_ONE_IMAGE)_DOCKERS += $(SONIC_INSTALL_DOCKER_IMAGES) SONIC_INSTALLERS += $(SONIC_ONE_IMAGE) diff --git a/platform/barefoot/rules.mk b/platform/barefoot/rules.mk index c339b81699c1..a482c1d12fa8 100644 --- a/platform/barefoot/rules.mk +++ b/platform/barefoot/rules.mk @@ -10,12 +10,13 @@ include $(PLATFORM_PATH)/libsaithrift-dev.mk include $(PLATFORM_PATH)/python-saithrift.mk include $(PLATFORM_PATH)/docker-ptf-bfn.mk include $(PLATFORM_PATH)/bfn-platform.mk +include $(PLATFORM_PATH)/bfn-platform-wnc.mk SONIC_ALL += $(SONIC_ONE_IMAGE) \ $(DOCKER_FPM) # Inject sai into sairedis -$(LIBSAIREDIS)_DEPENDS += $(BFN_SAI) $(BFN_PLATFORM)#$(LIBSAITHRIFT_DEV_BFN) +$(LIBSAIREDIS)_DEPENDS += $(BFN_SAI) $(BFN_PLATFORM) $(BFN_WNC_PLATFORM)#$(LIBSAITHRIFT_DEV_BFN) # Runtime dependency on sai is set only for syncd -$(SYNCD)_RDEPENDS += $(BFN_SAI) $(BFN_PLATFORM) +$(SYNCD)_RDEPENDS += $(BFN_SAI) $(BFN_PLATFORM) $(BFN_WNC_PLATFORM) From 369b67d3409acd8eab511109c6415b3d91fbb6ca Mon Sep 17 00:00:00 2001 From: Brand Date: Thu, 1 Feb 2018 11:19:58 +0800 Subject: [PATCH 33/58] Revert bfn-platform.mk --- platform/barefoot/bfn-platform.mk | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/platform/barefoot/bfn-platform.mk b/platform/barefoot/bfn-platform.mk index 0851626880be..b50a7d51c0f6 100644 --- a/platform/barefoot/bfn-platform.mk +++ b/platform/barefoot/bfn-platform.mk @@ -1,6 +1,5 @@ BFN_PLATFORM = bfnplatform_1.0.0_amd64.deb -#$(BFN_PLATFORM)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/rel_7_0/bfnplatform_1.0.0_amd64.deb" -$(BFN_PLATFORM)_URL = "https://github.com/YaoTien/download/raw/master/sonic/sde/7_0_0_18/bfnplatform_1.0.0_amd64.deb" +$(BFN_PLATFORM)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/rel_7_0/bfnplatform_1.0.0_amd64.deb" SONIC_ONLINE_DEBS += $(BFN_PLATFORM) # $(BFN_SAI_DEV) $(BFN_SAI_DEV)_DEPENDS += $(BFN_PLATFORM) From 5bc6dbca5031c24dc5c06fdc96a092175ef1fc59 Mon Sep 17 00:00:00 2001 From: YaoTien Date: Sat, 3 Feb 2018 10:54:21 +0800 Subject: [PATCH 34/58] Update bfn-platform-wnc.mk Update parameter name --- platform/barefoot/bfn-platform-wnc.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/barefoot/bfn-platform-wnc.mk b/platform/barefoot/bfn-platform-wnc.mk index 57ef0e14211b..1d2a9a159d6b 100644 --- a/platform/barefoot/bfn-platform-wnc.mk +++ b/platform/barefoot/bfn-platform-wnc.mk @@ -1,5 +1,5 @@ -BFN_PLATFORM = bfnplatformwnc_1.0.0_amd64.deb -$(BFN_PLATFORM)_URL = "https://github.com/YaoTien/download/raw/master/sonic/sde/7_0_0_18/bfnplatformwnc_1.0.0_amd64.deb" +BFN_WNC_PLATFORM = bfnplatformwnc_1.0.0_amd64.deb +$(BFN_WNC_PLATFORM)_URL = "https://github.com/YaoTien/download/raw/master/sonic/sde/7_0_0_18/bfnplatformwnc_1.0.0_amd64.deb" SONIC_ONLINE_DEBS += $(BFN_WNC_PLATFORM) # $(BFN_SAI_DEV) $(BFN_SAI_DEV)_DEPENDS += $(BFN_WNC_PLATFORM) From 8d2053ceb3e6f3f791fb8c4b0f0a3367cd5d2847 Mon Sep 17 00:00:00 2001 From: Brand Date: Tue, 6 Feb 2018 11:18:15 +0800 Subject: [PATCH 35/58] Update parameter name --- platform/barefoot/bfn-platform-wnc.mk | 8 ++++---- platform/barefoot/rules.mk | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/platform/barefoot/bfn-platform-wnc.mk b/platform/barefoot/bfn-platform-wnc.mk index 1d2a9a159d6b..e2f45d35b2b8 100644 --- a/platform/barefoot/bfn-platform-wnc.mk +++ b/platform/barefoot/bfn-platform-wnc.mk @@ -1,5 +1,5 @@ -BFN_WNC_PLATFORM = bfnplatformwnc_1.0.0_amd64.deb -$(BFN_WNC_PLATFORM)_URL = "https://github.com/YaoTien/download/raw/master/sonic/sde/7_0_0_18/bfnplatformwnc_1.0.0_amd64.deb" +WNC_OSW1800_PLATFORM = bfnplatformwnc_1.0.0_amd64.deb +$(WNC_OSW1800_PLATFORM)_URL = "https://github.com/YaoTien/download/raw/master/sonic/sde/7_0_0_18/bfnplatformwnc_1.0.0_amd64.deb" -SONIC_ONLINE_DEBS += $(BFN_WNC_PLATFORM) # $(BFN_SAI_DEV) -$(BFN_SAI_DEV)_DEPENDS += $(BFN_WNC_PLATFORM) +SONIC_ONLINE_DEBS += $(WNC_OSW1800_PLATFORM) # $(BFN_SAI_DEV) +$(BFN_SAI_DEV)_DEPENDS += $(WNC_OSW1800_PLATFORM) diff --git a/platform/barefoot/rules.mk b/platform/barefoot/rules.mk index a482c1d12fa8..c308ec08ee3d 100644 --- a/platform/barefoot/rules.mk +++ b/platform/barefoot/rules.mk @@ -16,7 +16,7 @@ SONIC_ALL += $(SONIC_ONE_IMAGE) \ $(DOCKER_FPM) # Inject sai into sairedis -$(LIBSAIREDIS)_DEPENDS += $(BFN_SAI) $(BFN_PLATFORM) $(BFN_WNC_PLATFORM)#$(LIBSAITHRIFT_DEV_BFN) +$(LIBSAIREDIS)_DEPENDS += $(BFN_SAI) $(BFN_PLATFORM) $(WNC_OSW1800_PLATFORM)#$(LIBSAITHRIFT_DEV_BFN) # Runtime dependency on sai is set only for syncd -$(SYNCD)_RDEPENDS += $(BFN_SAI) $(BFN_PLATFORM) $(BFN_WNC_PLATFORM) +$(SYNCD)_RDEPENDS += $(BFN_SAI) $(BFN_PLATFORM) $(WNC_OSW1800_PLATFORM) From 18e861777ab4e61c32db5d0fda3d4fb6bf4bf497 Mon Sep 17 00:00:00 2001 From: kram Date: Wed, 7 Feb 2018 11:43:51 -0800 Subject: [PATCH 36/58] initial support for WNC platform --- platform/barefoot/bfn-platform-wnc.mk | 1 + platform/barefoot/bfn-sai.mk | 4 +--- platform/barefoot/rules.mk | 4 ++-- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/platform/barefoot/bfn-platform-wnc.mk b/platform/barefoot/bfn-platform-wnc.mk index 1d2a9a159d6b..b2cb7c316d86 100644 --- a/platform/barefoot/bfn-platform-wnc.mk +++ b/platform/barefoot/bfn-platform-wnc.mk @@ -1,5 +1,6 @@ BFN_WNC_PLATFORM = bfnplatformwnc_1.0.0_amd64.deb $(BFN_WNC_PLATFORM)_URL = "https://github.com/YaoTien/download/raw/master/sonic/sde/7_0_0_18/bfnplatformwnc_1.0.0_amd64.deb" +#$(BFN_WNC_PLATFORM)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/rel_7_0/bfnplatformwnc_1.0.0_amd64.deb" SONIC_ONLINE_DEBS += $(BFN_WNC_PLATFORM) # $(BFN_SAI_DEV) $(BFN_SAI_DEV)_DEPENDS += $(BFN_WNC_PLATFORM) diff --git a/platform/barefoot/bfn-sai.mk b/platform/barefoot/bfn-sai.mk index 87b374d3a3aa..48c5b431df43 100644 --- a/platform/barefoot/bfn-sai.mk +++ b/platform/barefoot/bfn-sai.mk @@ -1,7 +1,5 @@ BFN_SAI = bfnsdk_1.0.0_amd64.deb -#$(BFN_SAI)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/rel_7_0/bfnsdk_1.0.0_amd64.deb" -$(BFN_SAI)_URL = "https://github.com/YaoTien/download/raw/master/sonic/sde/7_0_0_18/bfnsdk_1.0.0_amd64.deb" -# $(BFN_SAI_DEV)_URL = "https://www.dropbox.com/s/4ljk6hzw82rudsr/bfnsdk_1.0.0_amd64.deb?dl=0" +$(BFN_SAI)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/rel_7_0/bfnsdk_1.0.0_amd64.deb" SONIC_ONLINE_DEBS += $(BFN_SAI) # $(BFN_SAI_DEV) $(BFN_SAI_DEV)_DEPENDS += $(BFN_SAI) diff --git a/platform/barefoot/rules.mk b/platform/barefoot/rules.mk index a482c1d12fa8..b0dd7e60222b 100644 --- a/platform/barefoot/rules.mk +++ b/platform/barefoot/rules.mk @@ -16,7 +16,7 @@ SONIC_ALL += $(SONIC_ONE_IMAGE) \ $(DOCKER_FPM) # Inject sai into sairedis -$(LIBSAIREDIS)_DEPENDS += $(BFN_SAI) $(BFN_PLATFORM) $(BFN_WNC_PLATFORM)#$(LIBSAITHRIFT_DEV_BFN) +$(LIBSAIREDIS)_DEPENDS += $(BFN_SAI) $(BFN_WNC_PLATFORM) $(BFN_PLATFORM)#$(LIBSAITHRIFT_DEV_BFN) # Runtime dependency on sai is set only for syncd -$(SYNCD)_RDEPENDS += $(BFN_SAI) $(BFN_PLATFORM) $(BFN_WNC_PLATFORM) +$(SYNCD)_RDEPENDS += $(BFN_SAI) $(BFN_WNC_PLATFORM) $(BFN_PLATFORM) From 749714def3d0685fab088697e5afbd2980c9c9c2 Mon Sep 17 00:00:00 2001 From: kram Date: Wed, 14 Feb 2018 11:06:14 -0800 Subject: [PATCH 37/58] change switch name to "switch" --- .../minigraph.xml | 138 +++++++++--------- .../minigraph.xml | 138 +++++++++--------- 2 files changed, 138 insertions(+), 138 deletions(-) diff --git a/device/barefoot/x86_64-accton_wedge100bf_32x-r0/minigraph.xml b/device/barefoot/x86_64-accton_wedge100bf_32x-r0/minigraph.xml index 20637fc43459..60d93ad69d66 100644 --- a/device/barefoot/x86_64-accton_wedge100bf_32x-r0/minigraph.xml +++ b/device/barefoot/x86_64-accton_wedge100bf_32x-r0/minigraph.xml @@ -5,14 +5,14 @@ ARISTA01T0 10.0.0.33 - switch2 + switch 10.0.0.32 1 180 60 - switch2 + switch 10.0.0.0 ARISTA01T2 10.0.0.1 @@ -23,14 +23,14 @@ ARISTA02T0 10.0.0.35 - switch2 + switch 10.0.0.34 1 180 60 - switch2 + switch 10.0.0.2 ARISTA02T2 10.0.0.3 @@ -41,14 +41,14 @@ ARISTA03T0 10.0.0.37 - switch2 + switch 10.0.0.36 1 180 60 - switch2 + switch 10.0.0.4 ARISTA03T2 10.0.0.5 @@ -59,14 +59,14 @@ ARISTA04T0 10.0.0.39 - switch2 + switch 10.0.0.38 1 180 60 - switch2 + switch 10.0.0.6 ARISTA04T2 10.0.0.7 @@ -77,14 +77,14 @@ ARISTA05T0 10.0.0.41 - switch2 + switch 10.0.0.40 1 180 60 - switch2 + switch 10.0.0.8 ARISTA05T2 10.0.0.9 @@ -95,14 +95,14 @@ ARISTA06T0 10.0.0.43 - switch2 + switch 10.0.0.42 1 180 60 - switch2 + switch 10.0.0.10 ARISTA06T2 10.0.0.11 @@ -113,14 +113,14 @@ ARISTA07T0 10.0.0.45 - switch2 + switch 10.0.0.44 1 180 60 - switch2 + switch 10.0.0.12 ARISTA07T2 10.0.0.13 @@ -131,14 +131,14 @@ ARISTA08T0 10.0.0.47 - switch2 + switch 10.0.0.46 1 180 60 - switch2 + switch 10.0.0.14 ARISTA08T2 10.0.0.15 @@ -149,14 +149,14 @@ ARISTA09T0 10.0.0.49 - switch2 + switch 10.0.0.48 1 180 60 - switch2 + switch 10.0.0.16 ARISTA09T2 10.0.0.17 @@ -167,14 +167,14 @@ ARISTA10T0 10.0.0.51 - switch2 + switch 10.0.0.50 1 180 60 - switch2 + switch 10.0.0.18 ARISTA10T2 10.0.0.19 @@ -185,14 +185,14 @@ ARISTA11T0 10.0.0.53 - switch2 + switch 10.0.0.52 1 180 60 - switch2 + switch 10.0.0.20 ARISTA11T2 10.0.0.21 @@ -203,14 +203,14 @@ ARISTA12T0 10.0.0.55 - switch2 + switch 10.0.0.54 1 180 60 - switch2 + switch 10.0.0.22 ARISTA12T2 10.0.0.23 @@ -221,14 +221,14 @@ ARISTA13T0 10.0.0.57 - switch2 + switch 10.0.0.56 1 180 60 - switch2 + switch 10.0.0.24 ARISTA13T2 10.0.0.25 @@ -239,14 +239,14 @@ ARISTA14T0 10.0.0.59 - switch2 + switch 10.0.0.58 1 180 60 - switch2 + switch 10.0.0.26 ARISTA14T2 10.0.0.27 @@ -257,14 +257,14 @@ ARISTA15T0 10.0.0.61 - switch2 + switch 10.0.0.60 1 180 60 - switch2 + switch 10.0.0.28 ARISTA15T2 10.0.0.29 @@ -275,14 +275,14 @@ ARISTA16T0 10.0.0.63 - switch2 + switch 10.0.0.62 1 180 60 - switch2 + switch 10.0.0.30 ARISTA16T2 10.0.0.31 @@ -294,7 +294,7 @@ 65100 - switch2 + switch
10.0.0.33
@@ -639,7 +639,7 @@ - switch2 + switch @@ -814,224 +814,224 @@ DeviceInterfaceLink - switch2 + switch Ethernet0 ARISTA01T2 Ethernet1 DeviceInterfaceLink - switch2 + switch Ethernet4 ARISTA02T2 Ethernet1 DeviceInterfaceLink - switch2 + switch Ethernet8 ARISTA03T2 Ethernet1 DeviceInterfaceLink - switch2 + switch Ethernet12 ARISTA04T2 Ethernet1 DeviceInterfaceLink - switch2 + switch Ethernet16 ARISTA05T2 Ethernet1 DeviceInterfaceLink - switch2 + switch Ethernet20 ARISTA06T2 Ethernet1 DeviceInterfaceLink - switch2 + switch Ethernet24 ARISTA07T2 Ethernet1 DeviceInterfaceLink - switch2 + switch Ethernet28 ARISTA08T2 Ethernet1 DeviceInterfaceLink - switch2 + switch Ethernet32 ARISTA09T2 Ethernet1 DeviceInterfaceLink - switch2 + switch Ethernet36 ARISTA10T2 Ethernet1 DeviceInterfaceLink - switch2 + switch Ethernet40 ARISTA11T2 Ethernet1 DeviceInterfaceLink - switch2 + switch Ethernet44 ARISTA12T2 Ethernet1 DeviceInterfaceLink - switch2 + switch Ethernet48 ARISTA13T2 Ethernet1 DeviceInterfaceLink - switch2 + switch Ethernet52 ARISTA14T2 Ethernet1 DeviceInterfaceLink - switch2 + switch Ethernet56 ARISTA15T2 Ethernet1 DeviceInterfaceLink - switch2 + switch Ethernet60 ARISTA16T2 Ethernet1 DeviceInterfaceLink - switch2 + switch Ethernet64 ARISTA01T0 Ethernet1 DeviceInterfaceLink - switch2 + switch Ethernet68 ARISTA02T0 Ethernet1 DeviceInterfaceLink - switch2 + switch Ethernet72 ARISTA03T0 Ethernet1 DeviceInterfaceLink - switch2 + switch Ethernet76 ARISTA04T0 Ethernet1 DeviceInterfaceLink - switch2 + switch Ethernet80 ARISTA05T0 Ethernet1 DeviceInterfaceLink - switch2 + switch Ethernet84 ARISTA06T0 Ethernet1 DeviceInterfaceLink - switch2 + switch Ethernet88 ARISTA07T0 Ethernet1 DeviceInterfaceLink - switch2 + switch Ethernet92 ARISTA08T0 Ethernet1 DeviceInterfaceLink - switch2 + switch Ethernet96 ARISTA09T0 Ethernet1 DeviceInterfaceLink - switch2 + switch Ethernet100 ARISTA10T0 Ethernet1 DeviceInterfaceLink - switch2 + switch Ethernet104 ARISTA11T0 Ethernet1 DeviceInterfaceLink - switch2 + switch Ethernet108 ARISTA12T0 Ethernet1 DeviceInterfaceLink - switch2 + switch Ethernet112 ARISTA13T0 Ethernet1 DeviceInterfaceLink - switch2 + switch Ethernet116 ARISTA14T0 Ethernet1 DeviceInterfaceLink - switch2 + switch Ethernet120 ARISTA15T0 Ethernet1 DeviceInterfaceLink - switch2 + switch Ethernet124 ARISTA16T0 Ethernet1 @@ -1039,7 +1039,7 @@ - switch2 + switch montara ` @@ -1047,7 +1047,7 @@ - switch2 + switch DhcpResources @@ -1074,6 +1074,6 @@ - switch2 + switch montara
diff --git a/device/barefoot/x86_64-accton_wedge100bf_65x-r0/minigraph.xml b/device/barefoot/x86_64-accton_wedge100bf_65x-r0/minigraph.xml index 61f7b9c85a3c..18d614739737 100644 --- a/device/barefoot/x86_64-accton_wedge100bf_65x-r0/minigraph.xml +++ b/device/barefoot/x86_64-accton_wedge100bf_65x-r0/minigraph.xml @@ -5,14 +5,14 @@ ARISTA01T0 10.0.0.33 - switch2 + switch 10.0.0.32 1 180 60 - switch2 + switch 10.0.0.0 ARISTA01T2 10.0.0.1 @@ -23,14 +23,14 @@ ARISTA02T0 10.0.0.35 - switch2 + switch 10.0.0.34 1 180 60 - switch2 + switch 10.0.0.2 ARISTA02T2 10.0.0.3 @@ -41,14 +41,14 @@ ARISTA03T0 10.0.0.37 - switch2 + switch 10.0.0.36 1 180 60 - switch2 + switch 10.0.0.4 ARISTA03T2 10.0.0.5 @@ -59,14 +59,14 @@ ARISTA04T0 10.0.0.39 - switch2 + switch 10.0.0.38 1 180 60 - switch2 + switch 10.0.0.6 ARISTA04T2 10.0.0.7 @@ -77,14 +77,14 @@ ARISTA05T0 10.0.0.41 - switch2 + switch 10.0.0.40 1 180 60 - switch2 + switch 10.0.0.8 ARISTA05T2 10.0.0.9 @@ -95,14 +95,14 @@ ARISTA06T0 10.0.0.43 - switch2 + switch 10.0.0.42 1 180 60 - switch2 + switch 10.0.0.10 ARISTA06T2 10.0.0.11 @@ -113,14 +113,14 @@ ARISTA07T0 10.0.0.45 - switch2 + switch 10.0.0.44 1 180 60 - switch2 + switch 10.0.0.12 ARISTA07T2 10.0.0.13 @@ -131,14 +131,14 @@ ARISTA08T0 10.0.0.47 - switch2 + switch 10.0.0.46 1 180 60 - switch2 + switch 10.0.0.14 ARISTA08T2 10.0.0.15 @@ -149,14 +149,14 @@ ARISTA09T0 10.0.0.49 - switch2 + switch 10.0.0.48 1 180 60 - switch2 + switch 10.0.0.16 ARISTA09T2 10.0.0.17 @@ -167,14 +167,14 @@ ARISTA10T0 10.0.0.51 - switch2 + switch 10.0.0.50 1 180 60 - switch2 + switch 10.0.0.18 ARISTA10T2 10.0.0.19 @@ -185,14 +185,14 @@ ARISTA11T0 10.0.0.53 - switch2 + switch 10.0.0.52 1 180 60 - switch2 + switch 10.0.0.20 ARISTA11T2 10.0.0.21 @@ -203,14 +203,14 @@ ARISTA12T0 10.0.0.55 - switch2 + switch 10.0.0.54 1 180 60 - switch2 + switch 10.0.0.22 ARISTA12T2 10.0.0.23 @@ -221,14 +221,14 @@ ARISTA13T0 10.0.0.57 - switch2 + switch 10.0.0.56 1 180 60 - switch2 + switch 10.0.0.24 ARISTA13T2 10.0.0.25 @@ -239,14 +239,14 @@ ARISTA14T0 10.0.0.59 - switch2 + switch 10.0.0.58 1 180 60 - switch2 + switch 10.0.0.26 ARISTA14T2 10.0.0.27 @@ -257,14 +257,14 @@ ARISTA15T0 10.0.0.61 - switch2 + switch 10.0.0.60 1 180 60 - switch2 + switch 10.0.0.28 ARISTA15T2 10.0.0.29 @@ -275,14 +275,14 @@ ARISTA16T0 10.0.0.63 - switch2 + switch 10.0.0.62 1 180 60 - switch2 + switch 10.0.0.30 ARISTA16T2 10.0.0.31 @@ -294,7 +294,7 @@ 65100 - switch2 + switch
10.0.0.33
@@ -639,7 +639,7 @@ - switch2 + switch @@ -814,224 +814,224 @@ DeviceInterfaceLink - switch2 + switch Ethernet0 ARISTA01T2 Ethernet1 DeviceInterfaceLink - switch2 + switch Ethernet4 ARISTA02T2 Ethernet1 DeviceInterfaceLink - switch2 + switch Ethernet8 ARISTA03T2 Ethernet1 DeviceInterfaceLink - switch2 + switch Ethernet12 ARISTA04T2 Ethernet1 DeviceInterfaceLink - switch2 + switch Ethernet16 ARISTA05T2 Ethernet1 DeviceInterfaceLink - switch2 + switch Ethernet20 ARISTA06T2 Ethernet1 DeviceInterfaceLink - switch2 + switch Ethernet24 ARISTA07T2 Ethernet1 DeviceInterfaceLink - switch2 + switch Ethernet28 ARISTA08T2 Ethernet1 DeviceInterfaceLink - switch2 + switch Ethernet32 ARISTA09T2 Ethernet1 DeviceInterfaceLink - switch2 + switch Ethernet36 ARISTA10T2 Ethernet1 DeviceInterfaceLink - switch2 + switch Ethernet40 ARISTA11T2 Ethernet1 DeviceInterfaceLink - switch2 + switch Ethernet44 ARISTA12T2 Ethernet1 DeviceInterfaceLink - switch2 + switch Ethernet48 ARISTA13T2 Ethernet1 DeviceInterfaceLink - switch2 + switch Ethernet52 ARISTA14T2 Ethernet1 DeviceInterfaceLink - switch2 + switch Ethernet56 ARISTA15T2 Ethernet1 DeviceInterfaceLink - switch2 + switch Ethernet60 ARISTA16T2 Ethernet1 DeviceInterfaceLink - switch2 + switch Ethernet64 ARISTA01T0 Ethernet1 DeviceInterfaceLink - switch2 + switch Ethernet68 ARISTA02T0 Ethernet1 DeviceInterfaceLink - switch2 + switch Ethernet72 ARISTA03T0 Ethernet1 DeviceInterfaceLink - switch2 + switch Ethernet76 ARISTA04T0 Ethernet1 DeviceInterfaceLink - switch2 + switch Ethernet80 ARISTA05T0 Ethernet1 DeviceInterfaceLink - switch2 + switch Ethernet84 ARISTA06T0 Ethernet1 DeviceInterfaceLink - switch2 + switch Ethernet88 ARISTA07T0 Ethernet1 DeviceInterfaceLink - switch2 + switch Ethernet92 ARISTA08T0 Ethernet1 DeviceInterfaceLink - switch2 + switch Ethernet96 ARISTA09T0 Ethernet1 DeviceInterfaceLink - switch2 + switch Ethernet100 ARISTA10T0 Ethernet1 DeviceInterfaceLink - switch2 + switch Ethernet104 ARISTA11T0 Ethernet1 DeviceInterfaceLink - switch2 + switch Ethernet108 ARISTA12T0 Ethernet1 DeviceInterfaceLink - switch2 + switch Ethernet112 ARISTA13T0 Ethernet1 DeviceInterfaceLink - switch2 + switch Ethernet116 ARISTA14T0 Ethernet1 DeviceInterfaceLink - switch2 + switch Ethernet120 ARISTA15T0 Ethernet1 DeviceInterfaceLink - switch2 + switch Ethernet124 ARISTA16T0 Ethernet1 @@ -1039,7 +1039,7 @@ - switch2 + switch mavericks ` @@ -1047,7 +1047,7 @@ - switch2 + switch DhcpResources @@ -1074,6 +1074,6 @@ - switch2 + switch mavericks
From 4f4422663e01a70b0bc64e7a0d5ab950217b2875 Mon Sep 17 00:00:00 2001 From: wadelnn Date: Thu, 22 Feb 2018 20:15:12 +0800 Subject: [PATCH 38/58] Add Ingrasys S9180 platform Signed-off-by: Wade He --- .../INGRASYS-S9180-32X/port_config.ini | 33 ++ .../INGRASYS-S9180-32X/sai.profile | 1 + .../INGRASYS-S9180-32X/switch-sai.conf | 33 ++ .../x86_64-ingrasys_s9180_32x-r0/fancontrol | 12 + .../installer.conf | 3 + .../minigraph.xml | 151 +++++++++ .../plugins/eeprom.py | 22 ++ .../plugins/sfputil.py | 290 ++++++++++++++++++ .../x86_64-ingrasys_s9180_32x-r0/sensors.conf | 76 +++++ platform/barefoot/bfn-platform-ingrasys.mk | 5 + platform/barefoot/one-image.mk | 1 + .../barefoot/platform-modules-ingrasys.mk | 11 + platform/barefoot/rules.mk | 7 +- .../barefoot/sonic-platform-modules-ingrasys | 1 + 14 files changed, 643 insertions(+), 3 deletions(-) create mode 100644 device/ingrasys/x86_64-ingrasys_s9180_32x-r0/INGRASYS-S9180-32X/port_config.ini create mode 100644 device/ingrasys/x86_64-ingrasys_s9180_32x-r0/INGRASYS-S9180-32X/sai.profile create mode 100644 device/ingrasys/x86_64-ingrasys_s9180_32x-r0/INGRASYS-S9180-32X/switch-sai.conf create mode 100644 device/ingrasys/x86_64-ingrasys_s9180_32x-r0/fancontrol create mode 100644 device/ingrasys/x86_64-ingrasys_s9180_32x-r0/installer.conf create mode 100644 device/ingrasys/x86_64-ingrasys_s9180_32x-r0/minigraph.xml create mode 100644 device/ingrasys/x86_64-ingrasys_s9180_32x-r0/plugins/eeprom.py create mode 100644 device/ingrasys/x86_64-ingrasys_s9180_32x-r0/plugins/sfputil.py create mode 100644 device/ingrasys/x86_64-ingrasys_s9180_32x-r0/sensors.conf create mode 100644 platform/barefoot/bfn-platform-ingrasys.mk create mode 100644 platform/barefoot/platform-modules-ingrasys.mk create mode 160000 platform/barefoot/sonic-platform-modules-ingrasys diff --git a/device/ingrasys/x86_64-ingrasys_s9180_32x-r0/INGRASYS-S9180-32X/port_config.ini b/device/ingrasys/x86_64-ingrasys_s9180_32x-r0/INGRASYS-S9180-32X/port_config.ini new file mode 100644 index 000000000000..855a02011934 --- /dev/null +++ b/device/ingrasys/x86_64-ingrasys_s9180_32x-r0/INGRASYS-S9180-32X/port_config.ini @@ -0,0 +1,33 @@ +# name lanes alias speed autoneg fec index +Ethernet0 0,1,2,3 Ethernet0 100000 0 0 0 +Ethernet4 4,5,6,7 Ethernet4 100000 0 0 1 +Ethernet8 8,9,10,11 Ethernet8 100000 0 0 2 +Ethernet12 12,13,14,15 Ethernet12 100000 0 0 3 +Ethernet16 16,17,18,19 Ethernet16 100000 0 0 4 +Ethernet20 20,21,22,23 Ethernet20 100000 0 0 5 +Ethernet24 24,25,26,27 Ethernet24 100000 0 0 6 +Ethernet28 28,29,30,31 Ethernet28 100000 0 0 7 +Ethernet32 32,33,34,35 Ethernet32 100000 0 0 8 +Ethernet36 36,37,38,39 Ethernet36 100000 0 0 9 +Ethernet40 40,41,42,43 Ethernet40 100000 0 0 10 +Ethernet44 44,45,46,47 Ethernet44 100000 0 0 11 +Ethernet48 48,49,50,51 Ethernet48 100000 0 0 12 +Ethernet52 52,53,54,55 Ethernet52 100000 0 0 13 +Ethernet56 56,57,58,59 Ethernet56 100000 0 0 14 +Ethernet60 60,61,62,63 Ethernet60 100000 0 0 15 +Ethernet64 64,65,66,67 Ethernet64 100000 0 0 16 +Ethernet68 68,69,70,71 Ethernet68 100000 0 0 17 +Ethernet72 72,73,74,75 Ethernet72 100000 0 0 18 +Ethernet76 76,77,78,79 Ethernet76 100000 0 0 19 +Ethernet80 80,81,82,83 Ethernet80 100000 0 0 20 +Ethernet84 84,85,86,87 Ethernet84 100000 0 0 21 +Ethernet88 88,89,90,91 Ethernet88 100000 0 0 22 +Ethernet92 92,93,94,95 Ethernet92 100000 0 0 23 +Ethernet96 96,97,98,99 Ethernet96 100000 0 0 24 +Ethernet100 100,101,102,103 Ethernet100 100000 0 0 25 +Ethernet104 104,105,106,107 Ethernet104 100000 0 0 26 +Ethernet108 108,109,110,111 Ethernet108 100000 0 0 27 +Ethernet112 112,113,114,115 Ethernet112 100000 0 0 28 +Ethernet116 116,117,118,119 Ethernet116 100000 0 0 29 +Ethernet120 120,121,122,123 Ethernet120 100000 0 0 30 +Ethernet124 124,125,126,127 Ethernet124 100000 0 0 31 diff --git a/device/ingrasys/x86_64-ingrasys_s9180_32x-r0/INGRASYS-S9180-32X/sai.profile b/device/ingrasys/x86_64-ingrasys_s9180_32x-r0/INGRASYS-S9180-32X/sai.profile new file mode 100644 index 000000000000..1e7e455bdc08 --- /dev/null +++ b/device/ingrasys/x86_64-ingrasys_s9180_32x-r0/INGRASYS-S9180-32X/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/etc/bf/th-s9180-32x100G.config.bf diff --git a/device/ingrasys/x86_64-ingrasys_s9180_32x-r0/INGRASYS-S9180-32X/switch-sai.conf b/device/ingrasys/x86_64-ingrasys_s9180_32x-r0/INGRASYS-S9180-32X/switch-sai.conf new file mode 100644 index 000000000000..4f316bb9e5af --- /dev/null +++ b/device/ingrasys/x86_64-ingrasys_s9180_32x-r0/INGRASYS-S9180-32X/switch-sai.conf @@ -0,0 +1,33 @@ +{ + "chip_list": [ + { + "id": "asic-0", + "chip_family": "Tofino", + "instance": 0, + "pcie_sysfs_prefix": "/sys/devices/pci0000:00/0000:00:03.0/0000:05:00.0", + "pcie_domain": 0, + "pcie_bus": 5, + "pcie_fn": 0, + "pcie_dev": 0, + "pcie_int_mode": 1, + "sds_fw_path": "share/tofino_sds_fw/avago/firmware" + } + ], + "instance": 0, + "p4_program_list": [ + { + "id": "pgm-0", + "instance": 0, + "path": "switch", + "program-name": "switch", + "pd": "lib/tofinopd/switch/libpd.so", + "pd-thrift": "lib/tofinopd/switch/libpdthrift.so", + "table-config": "share/tofinopd/switch/context.json", + "tofino-bin": "share/tofinopd/switch/tofino.bin", + "switchapi": "lib/libswitchapi.so", + "switchsai": "lib/libswitchsai.so", + "agent0": "lib/platform/x86_64-ingrasys_s9180_32x-r0/libpltfm_mgr.so", + "switchapi_port_add": false + } + ] +} diff --git a/device/ingrasys/x86_64-ingrasys_s9180_32x-r0/fancontrol b/device/ingrasys/x86_64-ingrasys_s9180_32x-r0/fancontrol new file mode 100644 index 000000000000..dc303afac034 --- /dev/null +++ b/device/ingrasys/x86_64-ingrasys_s9180_32x-r0/fancontrol @@ -0,0 +1,12 @@ +# Configuration file generated by pwmconfig, changes will be lost +INTERVAL=10 +DEVPATH=hwmon1=devices/pci0000:00/0000:00:1f.3/i2c-0/i2c-56/56-002f +DEVNAME=hwmon1=w83795adg +FCTEMPS=hwmon1/device/pwm2=hwmon2/temp2_input hwmon1/device/pwm1=hwmon2/temp2_input +FCFANS=hwmon1/device/pwm2=hwmon1/device/fan8_input hwmon1/device/pwm2=hwmon1/device/fan7_input hwmon1/device/pwm2=hwmon1/device/fan6_input hwmon1/device/pwm2=hwmon1/device/fan5_input hwmon1/device/pwm1=hwmon1/device/fan4_input hwmon1/device/pwm1=hwmon1/device/fan3_input hwmon1/device/pwm1=hwmon1/device/fan2_input hwmon1/device/pwm1=hwmon1/device/fan1_input +# TODO: check the temp value with HW after board ready +MINTEMP=hwmon1/device/pwm2=20 hwmon1/device/pwm1=20 +MAXTEMP=hwmon1/device/pwm2=60 hwmon1/device/pwm1=60 +MINSTART=hwmon1/device/pwm2=75 hwmon1/device/pwm1=75 +MINSTOP=hwmon1/device/pwm2=22 hwmon1/device/pwm1=22 + diff --git a/device/ingrasys/x86_64-ingrasys_s9180_32x-r0/installer.conf b/device/ingrasys/x86_64-ingrasys_s9180_32x-r0/installer.conf new file mode 100644 index 000000000000..925a32fc0c3a --- /dev/null +++ b/device/ingrasys/x86_64-ingrasys_s9180_32x-r0/installer.conf @@ -0,0 +1,3 @@ +CONSOLE_PORT=0x3f8 +CONSOLE_DEV=0 +CONSOLE_SPEED=115200 diff --git a/device/ingrasys/x86_64-ingrasys_s9180_32x-r0/minigraph.xml b/device/ingrasys/x86_64-ingrasys_s9180_32x-r0/minigraph.xml new file mode 100644 index 000000000000..e2d151e6ec47 --- /dev/null +++ b/device/ingrasys/x86_64-ingrasys_s9180_32x-r0/minigraph.xml @@ -0,0 +1,151 @@ + + + + + + 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 + + +
+
+ + + + + + HostIP + Loopback0 + + 100.0.0.9/32 + + 100.0.0.9/32 + + + + + + + + OCPSCH01040GGLF + + + + + + Ethernet0 + 10.10.1.25/30 + + + + Ethernet4 + 10.10.2.25/30 + + + + + + + + + + + + 40000 + DeviceInterfaceLink + OCPSCH0104001MS + Ethernet24 + OCPSCH01040GGLF + Ethernet0 + + + 40000 + DeviceInterfaceLink + OCPSCH0104002MS + Ethernet24 + OCPSCH01040GGLF + Ethernet4 + + + + + OCPSCH01040GGLF + INGRASYS-S9180-32X + + + + + + + OCPSCH01040GGLF + + + 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 + + + + + + + OCPSCH01040GGLF + INGRASYS-S9180-32X +
diff --git a/device/ingrasys/x86_64-ingrasys_s9180_32x-r0/plugins/eeprom.py b/device/ingrasys/x86_64-ingrasys_s9180_32x-r0/plugins/eeprom.py new file mode 100644 index 000000000000..d1270eeffbf6 --- /dev/null +++ b/device/ingrasys/x86_64-ingrasys_s9180_32x-r0/plugins/eeprom.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python + +############################################################################# +# Ingrasys S9180-32X +# +# 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: + 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-0055/eeprom" + super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/ingrasys/x86_64-ingrasys_s9180_32x-r0/plugins/sfputil.py b/device/ingrasys/x86_64-ingrasys_s9180_32x-r0/plugins/sfputil.py new file mode 100644 index 000000000000..e0f85a981182 --- /dev/null +++ b/device/ingrasys/x86_64-ingrasys_s9180_32x-r0/plugins/sfputil.py @@ -0,0 +1,290 @@ +# sfputil.py +# +# Platform-specific SFP transceiver interface for SONiC +# + +try: + import time + 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 = 33 + SFP_PORT_START = 32 + PORTS_IN_BLOCK = 34 + + BASE_DIR_PATH = "/sys/class/gpio/gpio{0}/direction" + BASE_VAL_PATH = "/sys/class/gpio/gpio{0}/value" + + _port_to_eeprom_mapping = {} + port_to_i2c_mapping = { + 0: 10, + 1: 9, + 2: 12, + 3: 11, + 4: 14, + 5: 13, + 6: 16, + 7: 15, + 8: 18, + 9: 17, + 10: 20, + 11: 19, + 12: 22, + 13: 21, + 14: 24, + 15: 23, + 16: 26, + 17: 25, + 18: 28, + 19: 27, + 20: 30, + 21: 29, + 22: 32, + 23: 31, + 24: 34, + 25: 33, + 26: 36, + 27: 35, + 28: 38, + 29: 37, + 30: 40, + 31: 39, + 32: 45, + 33: 46 + } + + abs_to_gpio_mapping = { + 0: 241, + 1: 240, + 2: 243, + 3: 242, + 4: 245, + 5: 244, + 6: 247, + 7: 246, + 8: 249, + 9: 248, + 10: 251, + 11: 250, + 12: 253, + 13: 252, + 14: 255, + 15: 254, + 16: 225, + 17: 224, + 18: 227, + 19: 226, + 20: 229, + 21: 228, + 22: 231, + 23: 230, + 24: 233, + 25: 232, + 26: 235, + 27: 234, + 28: 237, + 29: 236, + 30: 239, + 31: 238, + 32: 177, + 33: 176 + } + + lpmode_to_gpio_mapping = { + 0: 161, + 1: 160, + 2: 163, + 3: 162, + 4: 165, + 5: 164, + 6: 167, + 7: 166, + 8: 169, + 9: 168, + 10: 171, + 11: 170, + 12: 173, + 13: 172, + 14: 175, + 15: 174, + 16: 145, + 17: 144, + 18: 147, + 19: 146, + 20: 149, + 21: 148, + 22: 151, + 23: 150, + 24: 153, + 25: 152, + 26: 155, + 27: 154, + 28: 157, + 29: 156, + 30: 159, + 31: 158 + } + + reset_to_gpio_mapping = { + 0: 129, + 1: 128, + 2: 131, + 3: 130, + 4: 133, + 5: 132, + 6: 135, + 7: 134, + 8: 137, + 9: 136, + 10: 139, + 11: 138, + 12: 141, + 13: 140, + 14: 143, + 15: 142, + 16: 113, + 17: 112, + 18: 115, + 19: 114, + 20: 117, + 21: 116, + 22: 119, + 23: 118, + 24: 121, + 25: 120, + 26: 123, + 27: 122, + 28: 125, + 29: 124, + 30: 127, + 31: 126 + } + + @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 + @property + def sfp_port_start(self): + return self.SFP_PORT_START + + def __init__(self): + # Override port_to_eeprom_mapping for class initialization + eeprom_path = "/sys/class/i2c-adapter/i2c-{0}/{0}-0050/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 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: + abs_device_file = self.BASE_VAL_PATH.format( + self.abs_to_gpio_mapping[port_num]) + val_file = open(abs_device_file) + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + content = val_file.readline().rstrip() + val_file.close() + + # content is a string, either "0" or "1" + if content == "1": + 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.sfp_port_start: # TBD + return False + + try: + lpmode_val_device_file = self.BASE_VAL_PATH.format( + self.lpmode_to_gpio_mapping[port_num]) + val_file = open(lpmode_val_device_file) + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + content = val_file.readline().rstrip() + val_file.close() + + # content is a string, either "0" or "1" + if content == "1": + return True + + 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.sfp_port_start: # TBD + return False + + try: + lpmode_val_device_file = self.BASE_VAL_PATH.format( + self.lpmode_to_gpio_mapping[port_num]) + val_file = open(lpmode_val_device_file, "w") + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + val_file.write("1" if lpmode is True else "0") + val_file.close() + + return True + + def reset(self, port_num): + # Check for invalid port_num + if port_num < self.port_start or port_num > self.sfp_port_start: # TBD + return False + + try: + reset_val_device_file = self.BASE_VAL_PATH.format( + self.reset_to_gpio_mapping[port_num]) + val_file = open(reset_val_device_file, "w") + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + val_file.write("1") + val_file.close() + + # Sleep 1 second to allow it to settle + time.sleep(1) + + try: + reset_val_device_file = self.BASE_VAL_PATH.format( + self.reset_to_gpio_mapping[port_num]) + val_file = open(reset_val_device_file, "w") + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + val_file.write("0") + val_file.close() + + return True diff --git a/device/ingrasys/x86_64-ingrasys_s9180_32x-r0/sensors.conf b/device/ingrasys/x86_64-ingrasys_s9180_32x-r0/sensors.conf new file mode 100644 index 000000000000..eb5a5b4b69f3 --- /dev/null +++ b/device/ingrasys/x86_64-ingrasys_s9180_32x-r0/sensors.conf @@ -0,0 +1,76 @@ +# libsensors configuration file +chip "i350bb-*" + ignore loc1 + +chip "jc42-*" + label temp1 "DIMM Temp" + set temp1_max 50 + set temp1_crit 85 + +bus "i2c-0" "I2C I801" +chip "tmp75-i2c-*-4f" + label temp1 "CPU Board Temp" + set temp1_max 50 + +bus "i2c-41" "i2c-7-switch (chan_id 0)" +chip "tmp75-i2c-*-48" + label temp1 "Near PSU1" + set temp1_max 50 +chip "tmp75-i2c-*-4a" + label temp1 "Rear MAC" + set temp1_max 50 +chip "tmp75-i2c-*-4b" + label temp1 "Near Port 32" + set temp1_max 50 +chip "tmp75-i2c-*-4d" + label temp1 "Near PSU2" + set temp1_max 50 +chip "lm86-i2c-*-4c" + label temp1 "Front MAC" + label temp2 "ASIC Core Temp" + set temp1_min 20 + set temp1_max 65 + set temp1_crit 70 + set temp2_min 20 + set temp2_max 70 + set temp2_crit 80 + +bus "i2c-56" "i2c-0-mux (chan_id 7)" +chip "w83795adg-*" + label in0 "0.9V" + set in0_max 0.927 + set in0_min 0.873 + label in1 "0.86V" + set in1_max 0.877 + set in1_min 0.843 + ignore in2 + ignore in3 + ignore in4 + ignore in5 + ignore in6 + ignore in7 + label in12 "2.5V" + #compute in12 (2*4*@)/10, @-(2*4*@/10) + compute in12 @/(1+(3/10)), @*(1+(3/10)) + set in12_max 2.625 + set in12_min 2.375 + # in12 and in13 are the same source + ignore in13 + ignore in14 + ignore in15 + ignore in16 + label fan1 "FANTRAY 1-A" + label fan2 "FANTRAY 1-B" + label fan3 "FANTRAY 2-A" + label fan4 "FANTRAY 2-B" + label fan5 "FANTRAY 3-A" + label fan6 "FANTRAY 3-B" + label fan7 "FANTRAY 4-A" + label fan8 "FANTRAY 4-B" + ignore temp1 + ignore temp2 + ignore temp3 + ignore temp4 + ignore temp5 + ignore temp6 + ignore intrusion0 diff --git a/platform/barefoot/bfn-platform-ingrasys.mk b/platform/barefoot/bfn-platform-ingrasys.mk new file mode 100644 index 000000000000..a85d69baab79 --- /dev/null +++ b/platform/barefoot/bfn-platform-ingrasys.mk @@ -0,0 +1,5 @@ +BFN_INGRASYS_PLATFORM = bfnplatform-ingrasys_1.0.0_amd64.deb +$(BFN_INGRASYS_PLATFORM)_URL = "https://github.com/Ingrasys-sonic/packages/raw/master/lib/bfnplatform-ingrasys_1.0.0_amd64.deb" + +SONIC_ONLINE_DEBS += $(BFN_INGRASYS_PLATFORM) # $(BFN_SAI_DEV) +$(BFN_SAI_DEV)_DEPENDS += $(BFN_INGRASYS_PLATFORM) diff --git a/platform/barefoot/one-image.mk b/platform/barefoot/one-image.mk index 8dc12e9fa8ca..5da028dbe6d4 100644 --- a/platform/barefoot/one-image.mk +++ b/platform/barefoot/one-image.mk @@ -6,5 +6,6 @@ $(SONIC_ONE_IMAGE)_IMAGE_TYPE = onie $(SONIC_ONE_IMAGE)_INSTALLS += $(BFN_PLATFORM_MODULE) $(SONIC_ONE_IMAGE)_INSTALLS += $(BFN_MONTARA_PLATFORM_MODULE) $(SONIC_ONE_IMAGE)_INSTALLS += $(WNC_OSW1800_PLATFORM_MODULE) +$(SONIC_ONE_IMAGE)_INSTALLS += $(INGRASYS_S9180_32X_PLATFORM_MODULE) $(SONIC_ONE_IMAGE)_DOCKERS += $(SONIC_INSTALL_DOCKER_IMAGES) SONIC_INSTALLERS += $(SONIC_ONE_IMAGE) diff --git a/platform/barefoot/platform-modules-ingrasys.mk b/platform/barefoot/platform-modules-ingrasys.mk new file mode 100644 index 000000000000..7204adb7e02d --- /dev/null +++ b/platform/barefoot/platform-modules-ingrasys.mk @@ -0,0 +1,11 @@ +# Ingrasys S9180-32X Platform modules + +INGRASYS_S9180_32X_PLATFORM_MODULE_VERSION = 1.1.0 + +export INGRASYS_S9180_32X_PLATFORM_MODULE_VERSION + +INGRASYS_S9180_32X_PLATFORM_MODULE = sonic-platform-ingrasys-s9180-32x_$(INGRASYS_S9180_32X_PLATFORM_MODULE_VERSION)_amd64.deb +$(INGRASYS_S9180_32X_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-ingrasys +$(INGRASYS_S9180_32X_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) +$(INGRASYS_S9180_32X_PLATFORM_MODULE)_PLATFORM = x86_64-ingrasys_s9180_32x-r0 +SONIC_DPKG_DEBS += $(INGRASYS_S9180_32X_PLATFORM_MODULE) diff --git a/platform/barefoot/rules.mk b/platform/barefoot/rules.mk index b0dd7e60222b..810851591ef5 100644 --- a/platform/barefoot/rules.mk +++ b/platform/barefoot/rules.mk @@ -1,6 +1,7 @@ include $(PLATFORM_PATH)/platform-modules-bfn.mk include $(PLATFORM_PATH)/platform-modules-bfn-montara.mk include $(PLATFORM_PATH)/platform-modules-wnc-osw1800.mk +include $(PLATFORM_PATH)/platform-modules-ingrasys.mk include $(PLATFORM_PATH)/bfn-sai.mk include $(PLATFORM_PATH)/docker-syncd-bfn.mk include $(PLATFORM_PATH)/docker-syncd-bfn-rpc.mk @@ -11,12 +12,12 @@ include $(PLATFORM_PATH)/python-saithrift.mk include $(PLATFORM_PATH)/docker-ptf-bfn.mk include $(PLATFORM_PATH)/bfn-platform.mk include $(PLATFORM_PATH)/bfn-platform-wnc.mk - +include $(PLATFORM_PATH)/bfn-platform-ingrasys.mk SONIC_ALL += $(SONIC_ONE_IMAGE) \ $(DOCKER_FPM) # Inject sai into sairedis -$(LIBSAIREDIS)_DEPENDS += $(BFN_SAI) $(BFN_WNC_PLATFORM) $(BFN_PLATFORM)#$(LIBSAITHRIFT_DEV_BFN) +$(LIBSAIREDIS)_DEPENDS += $(BFN_SAI) $(BFN_WNC_PLATFORM) $(BFN_INGRASYS_PLATFORM) $(BFN_PLATFORM)#$(LIBSAITHRIFT_DEV_BFN) # Runtime dependency on sai is set only for syncd -$(SYNCD)_RDEPENDS += $(BFN_SAI) $(BFN_WNC_PLATFORM) $(BFN_PLATFORM) +$(SYNCD)_RDEPENDS += $(BFN_SAI) $(BFN_WNC_PLATFORM) $(BFN_INGRASYS_PLATFORM) $(BFN_PLATFORM) diff --git a/platform/barefoot/sonic-platform-modules-ingrasys b/platform/barefoot/sonic-platform-modules-ingrasys new file mode 160000 index 000000000000..7e7470b03af8 --- /dev/null +++ b/platform/barefoot/sonic-platform-modules-ingrasys @@ -0,0 +1 @@ +Subproject commit 7e7470b03af88589df2056629f6832078ff02a56 From 7fb248ccd4a492ed5e0952e0eabfa67249ab350e Mon Sep 17 00:00:00 2001 From: wadelnn Date: Thu, 22 Feb 2018 20:20:11 +0800 Subject: [PATCH 39/58] Modify bfnsdk for Ingrasys S9180 platform Signed-off-by: Wade He --- platform/barefoot/bfn-sai.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/barefoot/bfn-sai.mk b/platform/barefoot/bfn-sai.mk index 48c5b431df43..4ee0312bfcbd 100644 --- a/platform/barefoot/bfn-sai.mk +++ b/platform/barefoot/bfn-sai.mk @@ -1,5 +1,5 @@ BFN_SAI = bfnsdk_1.0.0_amd64.deb -$(BFN_SAI)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/rel_7_0/bfnsdk_1.0.0_amd64.deb" +$(BFN_SAI)_URL = "https://github.com/Ingrasys-sonic/packages/raw/master/sai/bfnsdk_1.0.0_amd64.deb" SONIC_ONLINE_DEBS += $(BFN_SAI) # $(BFN_SAI_DEV) $(BFN_SAI_DEV)_DEPENDS += $(BFN_SAI) From 640be3f265fa6d50b273b76ffaf83ff0d86a8b82 Mon Sep 17 00:00:00 2001 From: wadelnn Date: Thu, 22 Feb 2018 20:27:31 +0800 Subject: [PATCH 40/58] Resolved the conflict. --- platform/barefoot/rules.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/barefoot/rules.mk b/platform/barefoot/rules.mk index 810851591ef5..736c6bbcd7da 100644 --- a/platform/barefoot/rules.mk +++ b/platform/barefoot/rules.mk @@ -17,7 +17,7 @@ SONIC_ALL += $(SONIC_ONE_IMAGE) \ $(DOCKER_FPM) # Inject sai into sairedis -$(LIBSAIREDIS)_DEPENDS += $(BFN_SAI) $(BFN_WNC_PLATFORM) $(BFN_INGRASYS_PLATFORM) $(BFN_PLATFORM)#$(LIBSAITHRIFT_DEV_BFN) +$(LIBSAIREDIS)_DEPENDS += $(BFN_SAI) $(WNC_OSW1800_PLATFORM) $(BFN_INGRASYS_PLATFORM) $(BFN_PLATFORM)#$(LIBSAITHRIFT_DEV_BFN) # Runtime dependency on sai is set only for syncd -$(SYNCD)_RDEPENDS += $(BFN_SAI) $(BFN_WNC_PLATFORM) $(BFN_INGRASYS_PLATFORM) $(BFN_PLATFORM) +$(SYNCD)_RDEPENDS += $(BFN_SAI) $(WNC_OSW1800_PLATFORM) $(BFN_INGRASYS_PLATFORM) $(BFN_PLATFORM) From bb8d37942eab001316e85ca07b157efa8daef206 Mon Sep 17 00:00:00 2001 From: wadelnn Date: Thu, 22 Feb 2018 20:30:30 +0800 Subject: [PATCH 41/58] Resolved the conflict. --- platform/barefoot/rules.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/barefoot/rules.mk b/platform/barefoot/rules.mk index 736c6bbcd7da..f10952dfadc2 100644 --- a/platform/barefoot/rules.mk +++ b/platform/barefoot/rules.mk @@ -17,7 +17,7 @@ SONIC_ALL += $(SONIC_ONE_IMAGE) \ $(DOCKER_FPM) # Inject sai into sairedis -$(LIBSAIREDIS)_DEPENDS += $(BFN_SAI) $(WNC_OSW1800_PLATFORM) $(BFN_INGRASYS_PLATFORM) $(BFN_PLATFORM)#$(LIBSAITHRIFT_DEV_BFN) +$(LIBSAIREDIS)_DEPENDS += $(BFN_SAI) $(WNC_OSW1800_PLATFORM) $(BFN_INGRASYS_PLATFORM) $(BFN_PLATFORM) #$(LIBSAITHRIFT_DEV_BFN) # Runtime dependency on sai is set only for syncd $(SYNCD)_RDEPENDS += $(BFN_SAI) $(WNC_OSW1800_PLATFORM) $(BFN_INGRASYS_PLATFORM) $(BFN_PLATFORM) From 9582f479a0858262e4e526144a3743a071a5b7d7 Mon Sep 17 00:00:00 2001 From: wadelnn Date: Fri, 23 Feb 2018 10:02:32 +0800 Subject: [PATCH 42/58] Update submodule path and url. --- .gitmodules | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitmodules b/.gitmodules index 7aa9fa333bf2..0946020d4266 100644 --- a/.gitmodules +++ b/.gitmodules @@ -74,3 +74,6 @@ [submodule "platform/p4/SAI-P4-BM"] path = platform/p4/SAI-P4-BM url = https://github.com/Mellanox/SAI-P4-BM.git +[submodule "platform/barefoot/sonic-platform-modules-ingrasys"] + path = platform/barefoot/sonic-platform-modules-ingrasys + url = https://github.com/Ingrasys-sonic/sonic-platform-modules-ingrasys-barefoot.git From e2701e2807f805e1d66036fbe3f7c2ba2e7a2768 Mon Sep 17 00:00:00 2001 From: wadelnn Date: Sat, 24 Feb 2018 17:28:22 +0800 Subject: [PATCH 43/58] Delete unused file. --- .../x86_64-ingrasys_s9180_32x-r0/INGRASYS-S9180-32X/sai.profile | 1 - 1 file changed, 1 deletion(-) delete mode 100644 device/ingrasys/x86_64-ingrasys_s9180_32x-r0/INGRASYS-S9180-32X/sai.profile diff --git a/device/ingrasys/x86_64-ingrasys_s9180_32x-r0/INGRASYS-S9180-32X/sai.profile b/device/ingrasys/x86_64-ingrasys_s9180_32x-r0/INGRASYS-S9180-32X/sai.profile deleted file mode 100644 index 1e7e455bdc08..000000000000 --- a/device/ingrasys/x86_64-ingrasys_s9180_32x-r0/INGRASYS-S9180-32X/sai.profile +++ /dev/null @@ -1 +0,0 @@ -SAI_INIT_CONFIG_FILE=/etc/bf/th-s9180-32x100G.config.bf From c33aa95bc238fa353f78b881d69c7d5df88c679e Mon Sep 17 00:00:00 2001 From: wadelnn Date: Fri, 2 Mar 2018 18:13:54 +0800 Subject: [PATCH 44/58] Add psuutil in S9180-32X Signed-off-by: Wade He --- .../plugins/psuutil.py | 90 +++++++++++++++++++ .../barefoot/sonic-platform-modules-ingrasys | 2 +- 2 files changed, 91 insertions(+), 1 deletion(-) create mode 100644 device/ingrasys/x86_64-ingrasys_s9180_32x-r0/plugins/psuutil.py diff --git a/device/ingrasys/x86_64-ingrasys_s9180_32x-r0/plugins/psuutil.py b/device/ingrasys/x86_64-ingrasys_s9180_32x-r0/plugins/psuutil.py new file mode 100644 index 000000000000..8a719388266a --- /dev/null +++ b/device/ingrasys/x86_64-ingrasys_s9180_32x-r0/plugins/psuutil.py @@ -0,0 +1,90 @@ +# +# 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""" + + SYS_GPIO_DIR = "/sys/class/gpio/" + + 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 + gpio_path = [ 'gpio99/value', 'gpio96/value' ] + attr_path = self.SYS_GPIO_DIR + gpio_path[index-1] + + attr_value = self.get_attr_value(attr_path) + + if (attr_value != 'ERR'): + attr_value = int(attr_value, 10) + # 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 + gpio_path = [ 'gpio100/value', 'gpio97/value' ] + attr_path = self.SYS_GPIO_DIR + gpio_path[index-1] + + attr_value = self.get_attr_value(attr_path) + + if (attr_value != 'ERR'): + attr_value = int(attr_value, 10) + # Check for PSU status + if (attr_value == 1): + status = 1 + + return status + diff --git a/platform/barefoot/sonic-platform-modules-ingrasys b/platform/barefoot/sonic-platform-modules-ingrasys index 7e7470b03af8..c165fddbb8da 160000 --- a/platform/barefoot/sonic-platform-modules-ingrasys +++ b/platform/barefoot/sonic-platform-modules-ingrasys @@ -1 +1 @@ -Subproject commit 7e7470b03af88589df2056629f6832078ff02a56 +Subproject commit c165fddbb8da8bb11efc3c6952cb98949f2cdc87 From 8cb8e0fe44b9436f06b737cdc82e51daf399cb95 Mon Sep 17 00:00:00 2001 From: kram Date: Mon, 5 Mar 2018 17:58:21 -0800 Subject: [PATCH 45/58] update refpoint --- src/sonic-swss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-swss b/src/sonic-swss index 6ad7ece48fc4..7bf3da3138ad 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit 6ad7ece48fc4fa3a1c46fdf5cc507eddcdaf8496 +Subproject commit 7bf3da3138adf152fd03ce7db50f82bce272b551 From e6cbaa377bad5650234b1aa8a934774b65c7273a Mon Sep 17 00:00:00 2001 From: kram Date: Tue, 6 Mar 2018 18:07:08 -0800 Subject: [PATCH 46/58] update refpoint --- src/sonic-swss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-swss b/src/sonic-swss index 7bf3da3138ad..75aed6e67aa8 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit 7bf3da3138adf152fd03ce7db50f82bce272b551 +Subproject commit 75aed6e67aa8df1eaba4900cdc979aa7b55e6d78 From 434c6651e454ab96625523bf27af876537f6116c Mon Sep 17 00:00:00 2001 From: kram Date: Wed, 7 Mar 2018 09:39:59 -0800 Subject: [PATCH 47/58] change contact email, update refpoint --- .../INGRASYS-S9180-32X/port_config.ini | 66 +++++------ .../OSW1800-48x6q/port_config.ini | 108 +++++++++--------- .../debian/changelog | 2 +- .../debian/control | 2 +- .../debian/changelog | 2 +- .../sonic-platform-modules-bfn/debian/control | 2 +- src/sonic-swss | 2 +- 7 files changed, 92 insertions(+), 92 deletions(-) diff --git a/device/ingrasys/x86_64-ingrasys_s9180_32x-r0/INGRASYS-S9180-32X/port_config.ini b/device/ingrasys/x86_64-ingrasys_s9180_32x-r0/INGRASYS-S9180-32X/port_config.ini index 855a02011934..8b25c1333a67 100644 --- a/device/ingrasys/x86_64-ingrasys_s9180_32x-r0/INGRASYS-S9180-32X/port_config.ini +++ b/device/ingrasys/x86_64-ingrasys_s9180_32x-r0/INGRASYS-S9180-32X/port_config.ini @@ -1,33 +1,33 @@ -# name lanes alias speed autoneg fec index -Ethernet0 0,1,2,3 Ethernet0 100000 0 0 0 -Ethernet4 4,5,6,7 Ethernet4 100000 0 0 1 -Ethernet8 8,9,10,11 Ethernet8 100000 0 0 2 -Ethernet12 12,13,14,15 Ethernet12 100000 0 0 3 -Ethernet16 16,17,18,19 Ethernet16 100000 0 0 4 -Ethernet20 20,21,22,23 Ethernet20 100000 0 0 5 -Ethernet24 24,25,26,27 Ethernet24 100000 0 0 6 -Ethernet28 28,29,30,31 Ethernet28 100000 0 0 7 -Ethernet32 32,33,34,35 Ethernet32 100000 0 0 8 -Ethernet36 36,37,38,39 Ethernet36 100000 0 0 9 -Ethernet40 40,41,42,43 Ethernet40 100000 0 0 10 -Ethernet44 44,45,46,47 Ethernet44 100000 0 0 11 -Ethernet48 48,49,50,51 Ethernet48 100000 0 0 12 -Ethernet52 52,53,54,55 Ethernet52 100000 0 0 13 -Ethernet56 56,57,58,59 Ethernet56 100000 0 0 14 -Ethernet60 60,61,62,63 Ethernet60 100000 0 0 15 -Ethernet64 64,65,66,67 Ethernet64 100000 0 0 16 -Ethernet68 68,69,70,71 Ethernet68 100000 0 0 17 -Ethernet72 72,73,74,75 Ethernet72 100000 0 0 18 -Ethernet76 76,77,78,79 Ethernet76 100000 0 0 19 -Ethernet80 80,81,82,83 Ethernet80 100000 0 0 20 -Ethernet84 84,85,86,87 Ethernet84 100000 0 0 21 -Ethernet88 88,89,90,91 Ethernet88 100000 0 0 22 -Ethernet92 92,93,94,95 Ethernet92 100000 0 0 23 -Ethernet96 96,97,98,99 Ethernet96 100000 0 0 24 -Ethernet100 100,101,102,103 Ethernet100 100000 0 0 25 -Ethernet104 104,105,106,107 Ethernet104 100000 0 0 26 -Ethernet108 108,109,110,111 Ethernet108 100000 0 0 27 -Ethernet112 112,113,114,115 Ethernet112 100000 0 0 28 -Ethernet116 116,117,118,119 Ethernet116 100000 0 0 29 -Ethernet120 120,121,122,123 Ethernet120 100000 0 0 30 -Ethernet124 124,125,126,127 Ethernet124 100000 0 0 31 +# name lanes alias speed autoneg fec index +Ethernet0 0,1,2,3 Ethernet0 100000 0 none 0 +Ethernet4 4,5,6,7 Ethernet4 100000 0 none 1 +Ethernet8 8,9,10,11 Ethernet8 100000 0 none 2 +Ethernet12 12,13,14,15 Ethernet12 100000 0 none 3 +Ethernet16 16,17,18,19 Ethernet16 100000 0 none 4 +Ethernet20 20,21,22,23 Ethernet20 100000 0 none 5 +Ethernet24 24,25,26,27 Ethernet24 100000 0 none 6 +Ethernet28 28,29,30,31 Ethernet28 100000 0 none 7 +Ethernet32 32,33,34,35 Ethernet32 100000 0 none 8 +Ethernet36 36,37,38,39 Ethernet36 100000 0 none 9 +Ethernet40 40,41,42,43 Ethernet40 100000 0 none 10 +Ethernet44 44,45,46,47 Ethernet44 100000 0 none 11 +Ethernet48 48,49,50,51 Ethernet48 100000 0 none 12 +Ethernet52 52,53,54,55 Ethernet52 100000 0 none 13 +Ethernet56 56,57,58,59 Ethernet56 100000 0 none 14 +Ethernet60 60,61,62,63 Ethernet60 100000 0 none 15 +Ethernet64 64,65,66,67 Ethernet64 100000 0 none 16 +Ethernet68 68,69,70,71 Ethernet68 100000 0 none 17 +Ethernet72 72,73,74,75 Ethernet72 100000 0 none 18 +Ethernet76 76,77,78,79 Ethernet76 100000 0 none 19 +Ethernet80 80,81,82,83 Ethernet80 100000 0 none 20 +Ethernet84 84,85,86,87 Ethernet84 100000 0 none 21 +Ethernet88 88,89,90,91 Ethernet88 100000 0 none 22 +Ethernet92 92,93,94,95 Ethernet92 100000 0 none 23 +Ethernet96 96,97,98,99 Ethernet96 100000 0 none 24 +Ethernet100 100,101,102,103 Ethernet100 100000 0 none 25 +Ethernet104 104,105,106,107 Ethernet104 100000 0 none 26 +Ethernet108 108,109,110,111 Ethernet108 100000 0 none 27 +Ethernet112 112,113,114,115 Ethernet112 100000 0 none 28 +Ethernet116 116,117,118,119 Ethernet116 100000 0 none 29 +Ethernet120 120,121,122,123 Ethernet120 100000 0 none 30 +Ethernet124 124,125,126,127 Ethernet124 100000 0 none 31 diff --git a/device/wnc/x86_64-wnc_osw1800-r0/OSW1800-48x6q/port_config.ini b/device/wnc/x86_64-wnc_osw1800-r0/OSW1800-48x6q/port_config.ini index f47ac7345b6c..578f59203d30 100644 --- a/device/wnc/x86_64-wnc_osw1800-r0/OSW1800-48x6q/port_config.ini +++ b/device/wnc/x86_64-wnc_osw1800-r0/OSW1800-48x6q/port_config.ini @@ -1,55 +1,55 @@ # name lanes alias speed autoneg fec -Ethernet0 0 Ethernet0 25000 1 1 -Ethernet4 1 Ethernet4 25000 1 1 -Ethernet8 2 Ethernet8 25000 1 1 -Ethernet12 3 Ethernet12 25000 1 1 -Ethernet16 4 Ethernet16 25000 1 1 -Ethernet20 5 Ethernet20 25000 1 1 -Ethernet24 6 Ethernet24 25000 1 1 -Ethernet28 7 Ethernet28 25000 1 1 -Ethernet32 8 Ethernet32 25000 1 1 -Ethernet36 9 Ethernet36 25000 1 1 -Ethernet40 10 Ethernet40 25000 1 1 -Ethernet44 11 Ethernet44 25000 1 1 -Ethernet48 12 Ethernet48 25000 1 1 -Ethernet52 13 Ethernet52 25000 1 1 -Ethernet56 14 Ethernet56 25000 1 1 -Ethernet60 15 Ethernet60 25000 1 1 -Ethernet64 16 Ethernet64 25000 1 1 -Ethernet68 17 Ethernet68 25000 1 1 -Ethernet72 18 Ethernet72 25000 1 1 -Ethernet76 19 Ethernet76 25000 1 1 -Ethernet80 20 Ethernet80 25000 1 1 -Ethernet84 21 Ethernet84 25000 1 1 -Ethernet88 22 Ethernet88 25000 1 1 -Ethernet92 23 Ethernet92 25000 1 1 -Ethernet96 24 Ethernet96 25000 1 1 -Ethernet100 25 Ethernet100 25000 1 1 -Ethernet104 26 Ethernet104 25000 1 1 -Ethernet108 27 Ethernet108 25000 1 1 -Ethernet112 28 Ethernet112 25000 1 1 -Ethernet116 29 Ethernet116 25000 1 1 -Ethernet120 30 Ethernet120 25000 1 1 -Ethernet124 31 Ethernet124 25000 1 1 -Ethernet128 32 Ethernet128 25000 1 1 -Ethernet132 33 Ethernet132 25000 1 1 -Ethernet136 34 Ethernet136 25000 1 1 -Ethernet140 35 Ethernet140 25000 1 1 -Ethernet144 36 Ethernet144 25000 1 1 -Ethernet148 37 Ethernet148 25000 1 1 -Ethernet152 38 Ethernet152 25000 1 1 -Ethernet156 39 Ethernet156 25000 1 1 -Ethernet160 40 Ethernet160 25000 1 1 -Ethernet164 41 Ethernet164 25000 1 1 -Ethernet168 42 Ethernet168 25000 1 1 -Ethernet172 43 Ethernet172 25000 1 1 -Ethernet176 44 Ethernet176 25000 1 1 -Ethernet180 45 Ethernet180 25000 1 1 -Ethernet184 46 Ethernet184 25000 1 1 -Ethernet188 47 Ethernet188 25000 1 1 -Ethernet192 48,49,50,51 Ethernet192 100000 1 1 -Ethernet196 52,53,54,55 Ethernet196 100000 1 1 -Ethernet200 56,57,58,59 Ethernet200 100000 1 1 -Ethernet204 60,61,62,63 Ethernet204 100000 1 1 -Ethernet208 64,65,66,67 Ethernet208 100000 1 1 -Ethernet212 68,69,70,71 Ethernet212 100000 1 1 +Ethernet0 0 Ethernet0 25000 1 rs +Ethernet4 1 Ethernet4 25000 1 rs +Ethernet8 2 Ethernet8 25000 1 rs +Ethernet12 3 Ethernet12 25000 1 rs +Ethernet16 4 Ethernet16 25000 1 rs +Ethernet20 5 Ethernet20 25000 1 rs +Ethernet24 6 Ethernet24 25000 1 rs +Ethernet28 7 Ethernet28 25000 1 rs +Ethernet32 8 Ethernet32 25000 1 rs +Ethernet36 9 Ethernet36 25000 1 rs +Ethernet40 10 Ethernet40 25000 1 rs +Ethernet44 11 Ethernet44 25000 1 rs +Ethernet48 12 Ethernet48 25000 1 rs +Ethernet52 13 Ethernet52 25000 1 rs +Ethernet56 14 Ethernet56 25000 1 rs +Ethernet60 15 Ethernet60 25000 1 rs +Ethernet64 16 Ethernet64 25000 1 rs +Ethernet68 17 Ethernet68 25000 1 rs +Ethernet72 18 Ethernet72 25000 1 rs +Ethernet76 19 Ethernet76 25000 1 rs +Ethernet80 20 Ethernet80 25000 1 rs +Ethernet84 21 Ethernet84 25000 1 rs +Ethernet88 22 Ethernet88 25000 1 rs +Ethernet92 23 Ethernet92 25000 1 rs +Ethernet96 24 Ethernet96 25000 1 rs +Ethernet100 25 Ethernet100 25000 1 rs +Ethernet104 26 Ethernet104 25000 1 rs +Ethernet108 27 Ethernet108 25000 1 rs +Ethernet112 28 Ethernet112 25000 1 rs +Ethernet116 29 Ethernet116 25000 1 rs +Ethernet120 30 Ethernet120 25000 1 rs +Ethernet124 31 Ethernet124 25000 1 rs +Ethernet128 32 Ethernet128 25000 1 rs +Ethernet132 33 Ethernet132 25000 1 rs +Ethernet136 34 Ethernet136 25000 1 rs +Ethernet140 35 Ethernet140 25000 1 rs +Ethernet144 36 Ethernet144 25000 1 rs +Ethernet148 37 Ethernet148 25000 1 rs +Ethernet152 38 Ethernet152 25000 1 rs +Ethernet156 39 Ethernet156 25000 1 rs +Ethernet160 40 Ethernet160 25000 1 rs +Ethernet164 41 Ethernet164 25000 1 rs +Ethernet168 42 Ethernet168 25000 1 rs +Ethernet172 43 Ethernet172 25000 1 rs +Ethernet176 44 Ethernet176 25000 1 rs +Ethernet180 45 Ethernet180 25000 1 rs +Ethernet184 46 Ethernet184 25000 1 rs +Ethernet188 47 Ethernet188 25000 1 rs +Ethernet192 48,49,50,51 Ethernet192 100000 1 rs +Ethernet196 52,53,54,55 Ethernet196 100000 1 rs +Ethernet200 56,57,58,59 Ethernet200 100000 1 rs +Ethernet204 60,61,62,63 Ethernet204 100000 1 rs +Ethernet208 64,65,66,67 Ethernet208 100000 1 rs +Ethernet212 68,69,70,71 Ethernet212 100000 1 rs diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/debian/changelog b/platform/barefoot/sonic-platform-modules-bfn-montara/debian/changelog index 070927fd784b..80c1d96d3445 100644 --- a/platform/barefoot/sonic-platform-modules-bfn-montara/debian/changelog +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/debian/changelog @@ -2,4 +2,4 @@ platform-modules-bfn-montara (1.0) unstable; urgency=low * Initial release - -- Shuotian Cheng Mon, 11 Nov 2015 11:11:11 -0800 + -- Support Mon, 11 Nov 2015 11:11:11 -0800 diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/debian/control b/platform/barefoot/sonic-platform-modules-bfn-montara/debian/control index 1281dffd3f4d..6937614b87a7 100644 --- a/platform/barefoot/sonic-platform-modules-bfn-montara/debian/control +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/debian/control @@ -1,7 +1,7 @@ Source: platform-modules-bfn-montara Section: main Priority: extra -Maintainer: Shuotian Cheng +Maintainer: Support Build-Depends: debhelper (>= 8.0.0), bzip2 Standards-Version: 3.9.3 diff --git a/platform/barefoot/sonic-platform-modules-bfn/debian/changelog b/platform/barefoot/sonic-platform-modules-bfn/debian/changelog index 47b18ef78fef..d5df34112672 100644 --- a/platform/barefoot/sonic-platform-modules-bfn/debian/changelog +++ b/platform/barefoot/sonic-platform-modules-bfn/debian/changelog @@ -2,4 +2,4 @@ platform-modules-bfn (1.0) unstable; urgency=low * Initial release - -- Shuotian Cheng Mon, 11 Nov 2015 11:11:11 -0800 + -- Support Mon, 11 Nov 2015 11:11:11 -0800 diff --git a/platform/barefoot/sonic-platform-modules-bfn/debian/control b/platform/barefoot/sonic-platform-modules-bfn/debian/control index 5bdcd7acfcd7..f293b77b5b0c 100644 --- a/platform/barefoot/sonic-platform-modules-bfn/debian/control +++ b/platform/barefoot/sonic-platform-modules-bfn/debian/control @@ -1,7 +1,7 @@ Source: platform-modules-bfn Section: main Priority: extra -Maintainer: Shuotian Cheng +Maintainer: support Build-Depends: debhelper (>= 8.0.0), bzip2 Standards-Version: 3.9.3 diff --git a/src/sonic-swss b/src/sonic-swss index 75aed6e67aa8..f7df97fc46e4 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit 75aed6e67aa8df1eaba4900cdc979aa7b55e6d78 +Subproject commit f7df97fc46e44068ec7c01bc7a9fd778b85aaaf0 From 8fff27e46b31b03774a61a6adf58862e86056d5c Mon Sep 17 00:00:00 2001 From: kram Date: Wed, 7 Mar 2018 14:51:59 -0800 Subject: [PATCH 48/58] cleanup and update kernel modules --- .../sonic-platform-modules-bfn-montara/MAINTAINERS | 4 ---- .../barefoot/sonic-platform-modules-bfn/MAINTAINERS | 3 --- .../sonic-platform-modules-bfn/modules/bf_kdrv.c | 11 ++++++++--- .../modules/bf_kdrv.c | 11 ++++++++--- 4 files changed, 16 insertions(+), 13 deletions(-) diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/MAINTAINERS b/platform/barefoot/sonic-platform-modules-bfn-montara/MAINTAINERS index 05b0cea082c7..ed64c7824250 100644 --- a/platform/barefoot/sonic-platform-modules-bfn-montara/MAINTAINERS +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/MAINTAINERS @@ -1,7 +1,3 @@ # This file describes the maintainers for sonic-platform-modules-bfn # See the SONiC project governance document for more information - -Name = "Daxay" -Email = "support@barefootnetworks.com" -Github = barefootnetworks Mailinglist = sonicproject@googlegroups.com diff --git a/platform/barefoot/sonic-platform-modules-bfn/MAINTAINERS b/platform/barefoot/sonic-platform-modules-bfn/MAINTAINERS index 05b0cea082c7..b9c62ce01546 100644 --- a/platform/barefoot/sonic-platform-modules-bfn/MAINTAINERS +++ b/platform/barefoot/sonic-platform-modules-bfn/MAINTAINERS @@ -1,7 +1,4 @@ # This file describes the maintainers for sonic-platform-modules-bfn # See the SONiC project governance document for more information -Name = "Daxay" -Email = "support@barefootnetworks.com" -Github = barefootnetworks Mailinglist = sonicproject@googlegroups.com diff --git a/platform/barefoot/sonic-platform-modules-bfn/modules/bf_kdrv.c b/platform/barefoot/sonic-platform-modules-bfn/modules/bf_kdrv.c index 5f084f6a040f..fd66ad09493a 100644 --- a/platform/barefoot/sonic-platform-modules-bfn/modules/bf_kdrv.c +++ b/platform/barefoot/sonic-platform-modules-bfn/modules/bf_kdrv.c @@ -58,7 +58,13 @@ #include #include #include -#include + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) + #include +#else + #include +#endif + #include #include #include @@ -591,7 +597,6 @@ static ssize_t bf_read(struct file *filep, char __user *buf, return -EINVAL; count = sizeof(s32); } - count = sizeof(s32)*BF_MSIX_ENTRY_CNT; do { set_current_state(TASK_INTERRUPTIBLE); @@ -611,7 +616,7 @@ static ssize_t bf_read(struct file *filep, char __user *buf, if (copy_to_user(buf, &event_count, count)) retval = -EFAULT; else { /* adjust the listener->event_count; */ - for (i = 0 ; i < BF_MSIX_ENTRY_CNT; i++) { + for (i = 0 ; i < (count/sizeof(s32)); i++) { if (cnt_match[i]) { listener->event_count[i] = event_count[i]; } diff --git a/platform/barefoot/sonic-platform-modules-wnc-osw1800/modules/bf_kdrv.c b/platform/barefoot/sonic-platform-modules-wnc-osw1800/modules/bf_kdrv.c index 5f084f6a040f..fd66ad09493a 100644 --- a/platform/barefoot/sonic-platform-modules-wnc-osw1800/modules/bf_kdrv.c +++ b/platform/barefoot/sonic-platform-modules-wnc-osw1800/modules/bf_kdrv.c @@ -58,7 +58,13 @@ #include #include #include -#include + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) + #include +#else + #include +#endif + #include #include #include @@ -591,7 +597,6 @@ static ssize_t bf_read(struct file *filep, char __user *buf, return -EINVAL; count = sizeof(s32); } - count = sizeof(s32)*BF_MSIX_ENTRY_CNT; do { set_current_state(TASK_INTERRUPTIBLE); @@ -611,7 +616,7 @@ static ssize_t bf_read(struct file *filep, char __user *buf, if (copy_to_user(buf, &event_count, count)) retval = -EFAULT; else { /* adjust the listener->event_count; */ - for (i = 0 ; i < BF_MSIX_ENTRY_CNT; i++) { + for (i = 0 ; i < (count/sizeof(s32)); i++) { if (cnt_match[i]) { listener->event_count[i] = event_count[i]; } From b02b29a984c297052b6a1f60ea09bade7cd062b2 Mon Sep 17 00:00:00 2001 From: kram Date: Mon, 12 Mar 2018 21:06:38 -0700 Subject: [PATCH 49/58] updates based on review --- dockers/docker-orchagent/swssconfig.sh | 6 +++++- files/image_config/interfaces/interfaces.j2 | 5 ++--- platform/barefoot/one-image.mk | 6 +++--- .../sonic-platform-modules-wnc-osw1800/debian/files | 1 - src/sonic-config-engine/tests/sample_output/interfaces | 5 ++--- 5 files changed, 12 insertions(+), 11 deletions(-) delete mode 100644 platform/barefoot/sonic-platform-modules-wnc-osw1800/debian/files diff --git a/dockers/docker-orchagent/swssconfig.sh b/dockers/docker-orchagent/swssconfig.sh index c8ee8759333c..007f0953aed5 100755 --- a/dockers/docker-orchagent/swssconfig.sh +++ b/dockers/docker-orchagent/swssconfig.sh @@ -27,7 +27,7 @@ fast_reboot HWSKU=`sonic-cfggen -d -v "DEVICE_METADATA['localhost']['hwsku']"` -SWSSCONFIG_ARGS="00-copp.config.json ipinip.json ports.json switch.json " +SWSSCONFIG_ARGS="00-copp.config.json ports.json switch.json " if [ "$HWSKU" == "Force10-S6000" ]; then SWSSCONFIG_ARGS+="td2.32ports.buffers.json td2.32ports.qos.json " @@ -42,6 +42,10 @@ elif [[ "$HWSKU" == "ACS-MSN27"* ]]; then SWSSCONFIG_ARGS+="msn27xx.32ports.buffers.json " fi +if [[ "$HWSKU" != "montara" ] && [ "$HWSKU" != "mavericks" ] && [ "$HWSKU" != "OSW1800-48x6q" ] && [ "$HWSKU" != "INGRASYS-S9180-32X"]]; then + SWSSCONFIG_ARGS+="ipinip.json " +fi + for file in $SWSSCONFIG_ARGS; do swssconfig /etc/swss/config.d/$file sleep 1 diff --git a/files/image_config/interfaces/interfaces.j2 b/files/image_config/interfaces/interfaces.j2 index 2687582af605..4ec20c3b61ee 100644 --- a/files/image_config/interfaces/interfaces.j2 +++ b/files/image_config/interfaces/interfaces.j2 @@ -20,9 +20,8 @@ iface lo {{ 'inet' if prefix | ipv4 else 'inet6' }} static {% block mgmt_interface %} # BMC interface auto usb0 -iface usb0 inet static - address 192.168.0.2 - netmask 255.255.255.0 +iface usb0 inet6 auto + # The management network interface auto eth0 {% if MGMT_INTERFACE %} diff --git a/platform/barefoot/one-image.mk b/platform/barefoot/one-image.mk index 5da028dbe6d4..a7b5d009516d 100644 --- a/platform/barefoot/one-image.mk +++ b/platform/barefoot/one-image.mk @@ -4,8 +4,8 @@ SONIC_ONE_IMAGE = sonic-barefoot.bin $(SONIC_ONE_IMAGE)_MACHINE = barefoot $(SONIC_ONE_IMAGE)_IMAGE_TYPE = onie $(SONIC_ONE_IMAGE)_INSTALLS += $(BFN_PLATFORM_MODULE) -$(SONIC_ONE_IMAGE)_INSTALLS += $(BFN_MONTARA_PLATFORM_MODULE) -$(SONIC_ONE_IMAGE)_INSTALLS += $(WNC_OSW1800_PLATFORM_MODULE) -$(SONIC_ONE_IMAGE)_INSTALLS += $(INGRASYS_S9180_32X_PLATFORM_MODULE) +$(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(BFN_MONTARA_PLATFORM_MODULE) +$(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(WNC_OSW1800_PLATFORM_MODULE) +$(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(INGRASYS_S9180_32X_PLATFORM_MODULE) $(SONIC_ONE_IMAGE)_DOCKERS += $(SONIC_INSTALL_DOCKER_IMAGES) SONIC_INSTALLERS += $(SONIC_ONE_IMAGE) diff --git a/platform/barefoot/sonic-platform-modules-wnc-osw1800/debian/files b/platform/barefoot/sonic-platform-modules-wnc-osw1800/debian/files deleted file mode 100644 index 6ec8776133dc..000000000000 --- a/platform/barefoot/sonic-platform-modules-wnc-osw1800/debian/files +++ /dev/null @@ -1 +0,0 @@ -platform-modules-wnc-osw1800_1.0_amd64.deb main extra diff --git a/src/sonic-config-engine/tests/sample_output/interfaces b/src/sonic-config-engine/tests/sample_output/interfaces index a9fe483aa5ad..8a63c6d6e278 100644 --- a/src/sonic-config-engine/tests/sample_output/interfaces +++ b/src/sonic-config-engine/tests/sample_output/interfaces @@ -17,9 +17,8 @@ iface lo inet6 static # # BMC interface auto usb0 -iface usb0 inet static - address 192.168.0.2 - netmask 255.255.255.0 +iface usb0 inet6 auto + # The management network interface auto eth0 iface eth0 inet static From ef4a3dcaa0bfc1c6249ad2bfbd1d5ef400852f45 Mon Sep 17 00:00:00 2001 From: kram Date: Mon, 12 Mar 2018 21:09:26 -0700 Subject: [PATCH 50/58] update refpoint --- src/sonic-swss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-swss b/src/sonic-swss index f7df97fc46e4..a12a2e59373a 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit f7df97fc46e44068ec7c01bc7a9fd778b85aaaf0 +Subproject commit a12a2e59373a4eab9cd913e3d054b48dea11c52d From ead78877af70c11f5734edc31b46735a0bc62aa8 Mon Sep 17 00:00:00 2001 From: kram Date: Tue, 13 Mar 2018 09:14:36 -0700 Subject: [PATCH 51/58] update refpoint --- src/sonic-swss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-swss b/src/sonic-swss index a12a2e59373a..5d049e864e08 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit a12a2e59373a4eab9cd913e3d054b48dea11c52d +Subproject commit 5d049e864e083de199a0359d7bbc03765c6c42f1 From bb0c10173a2062607f456489488460a52a3a5760 Mon Sep 17 00:00:00 2001 From: kram Date: Tue, 13 Mar 2018 18:47:02 -0700 Subject: [PATCH 52/58] fix typo in config script to check for platforms --- dockers/docker-orchagent/swssconfig.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dockers/docker-orchagent/swssconfig.sh b/dockers/docker-orchagent/swssconfig.sh index 007f0953aed5..bb1b91a319cf 100755 --- a/dockers/docker-orchagent/swssconfig.sh +++ b/dockers/docker-orchagent/swssconfig.sh @@ -42,7 +42,7 @@ elif [[ "$HWSKU" == "ACS-MSN27"* ]]; then SWSSCONFIG_ARGS+="msn27xx.32ports.buffers.json " fi -if [[ "$HWSKU" != "montara" ] && [ "$HWSKU" != "mavericks" ] && [ "$HWSKU" != "OSW1800-48x6q" ] && [ "$HWSKU" != "INGRASYS-S9180-32X"]]; then +if [ "$HWSKU" != "montara" ] && [ "$HWSKU" != "mavericks" ] && [ "$HWSKU" != "OSW1800-48x6q" ] && [ "$HWSKU" != "INGRASYS-S9180-32X"]; then SWSSCONFIG_ARGS+="ipinip.json " fi From 8cfe8fcf90c5f10ae61d46acf03332c8f241d786 Mon Sep 17 00:00:00 2001 From: kram Date: Tue, 13 Mar 2018 18:59:50 -0700 Subject: [PATCH 53/58] remove stale file --- .../barefoot/sonic-platform-modules-bfn-montara/debian/files | 1 - 1 file changed, 1 deletion(-) delete mode 100644 platform/barefoot/sonic-platform-modules-bfn-montara/debian/files diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/debian/files b/platform/barefoot/sonic-platform-modules-bfn-montara/debian/files deleted file mode 100644 index 73e471552221..000000000000 --- a/platform/barefoot/sonic-platform-modules-bfn-montara/debian/files +++ /dev/null @@ -1 +0,0 @@ -platform-modules-bfn-montara_1.0_amd64.deb main extra From e59e7f6a65a5ad99d1ea87676755d051fa956926 Mon Sep 17 00:00:00 2001 From: kram Date: Tue, 13 Mar 2018 19:06:21 -0700 Subject: [PATCH 54/58] resolve conflicts --- dockers/docker-orchagent/orchagent.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dockers/docker-orchagent/orchagent.sh b/dockers/docker-orchagent/orchagent.sh index 2bec34951e9b..af9e5b0766ab 100755 --- a/dockers/docker-orchagent/orchagent.sh +++ b/dockers/docker-orchagent/orchagent.sh @@ -18,6 +18,8 @@ if [ "$platform" == "broadcom" ]; then ORCHAGENT_ARGS+="-m $MAC_ADDRESS" elif [ "$platform" == "cavium" ]; then ORCHAGENT_ARGS+="-m $MAC_ADDRESS" +elif [ "$platform" == "nephos" ]; then + ORCHAGENT_ARGS+="-m $MAC_ADDRESS" elif [ "$platform" == "barefoot" ]; then ORCHAGENT_ARGS+="-m $MAC_ADDRESS" fi From e6be0f94e80b48a130a4c06583cb82b6eab98f33 Mon Sep 17 00:00:00 2001 From: kram Date: Tue, 13 Mar 2018 20:02:13 -0700 Subject: [PATCH 55/58] cleanup diffs with Azure repo and update SDK debs --- Makefile | 1 + platform/barefoot/bfn-sai.mk | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 025992aad547..d1a28f031748 100644 --- a/Makefile +++ b/Makefile @@ -57,6 +57,7 @@ SONIC_BUILD_INSTRUCTION := make \ BUILD_NUMBER=$(BUILD_NUMBER) \ ENABLE_DHCP_GRAPH_SERVICE=$(ENABLE_DHCP_GRAPH_SERVICE) \ SHUTDOWN_BGP_ON_START=$(SHUTDOWN_BGP_ON_START) \ + ENABLE_SYNCD_RPC=$(ENABLE_SYNCD_RPC) \ PASSWORD=$(PASSWORD) \ USERNAME=$(USERNAME) diff --git a/platform/barefoot/bfn-sai.mk b/platform/barefoot/bfn-sai.mk index 4ee0312bfcbd..09b8be3082ce 100644 --- a/platform/barefoot/bfn-sai.mk +++ b/platform/barefoot/bfn-sai.mk @@ -1,5 +1,6 @@ BFN_SAI = bfnsdk_1.0.0_amd64.deb -$(BFN_SAI)_URL = "https://github.com/Ingrasys-sonic/packages/raw/master/sai/bfnsdk_1.0.0_amd64.deb" +$(BFN_SAI)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/rel_7_0_1/bfnsdk_1.0.0_amd64.deb" + SONIC_ONLINE_DEBS += $(BFN_SAI) # $(BFN_SAI_DEV) $(BFN_SAI_DEV)_DEPENDS += $(BFN_SAI) From 46d24cfb704018505a0a17fc6570cadcda738664 Mon Sep 17 00:00:00 2001 From: kram Date: Thu, 15 Mar 2018 22:33:04 -0700 Subject: [PATCH 56/58] update refpoints to Azure --- .gitmodules | 12 +++--------- src/sonic-sairedis | 2 +- src/sonic-swss | 2 +- 3 files changed, 5 insertions(+), 11 deletions(-) diff --git a/.gitmodules b/.gitmodules index 2d98667b6556..ad21aaf26ab2 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,21 +1,15 @@ [submodule "sonic-swss-common"] path = src/sonic-swss-common - url = https://github.com/barefootnetworks/sonic-swss-common + url = https://github.com/Azure/sonic-swss-common [submodule "sonic-linux-kernel"] path = src/sonic-linux-kernel url = https://github.com/Azure/sonic-linux-kernel [submodule "sonic-sairedis"] path = src/sonic-sairedis - url = https://github.com/barefootnetworks/sonic-sairedis + url = https://github.com/Azure/sonic-sairedis [submodule "sonic-swss"] path = src/sonic-swss - url = https://github.com/barefootnetworks/sonic-swss -[submodule "src/p4-switch/switch"] - path = platform/p4/p4-switch/switch - url = https://github.com/krambn/switch -[submodule "src/p4-bmv2/behavioral-model"] - path = platform/p4/p4-bmv/behavioral-model - url = https://github.com/krambn/behavioral-model + url = https://github.com/Azure/sonic-swss [submodule "src/p4c-bm/p4c-bm"] path = platform/p4/p4c-bm/p4c-bm url = https://github.com/krambn/p4c-bm diff --git a/src/sonic-sairedis b/src/sonic-sairedis index bff6e2c641aa..c591e384408e 160000 --- a/src/sonic-sairedis +++ b/src/sonic-sairedis @@ -1 +1 @@ -Subproject commit bff6e2c641aae8d16431088ff86a7697147b057d +Subproject commit c591e384408ed778414840abd0c4d8d18a8ad2a3 diff --git a/src/sonic-swss b/src/sonic-swss index 5d049e864e08..ca555569de9e 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit 5d049e864e083de199a0359d7bbc03765c6c42f1 +Subproject commit ca555569de9e0b3774f91d53a6427b139bdf585d From 5c2cb1f2392d5752375e93c4cb41182dc61f283e Mon Sep 17 00:00:00 2001 From: kram Date: Fri, 16 Mar 2018 14:11:46 -0700 Subject: [PATCH 57/58] address review comments --- dockers/docker-bfn-sswsyncd-rpc/Dockerfile | 38 ---------------------- dockers/docker-bfn-sswsyncd/Dockerfile | 17 ---------- dockers/docker-orchagent/swssconfig.sh | 12 ++++--- dockers/docker-saiserver-bfn/start.sh | 8 ----- 4 files changed, 7 insertions(+), 68 deletions(-) delete mode 100644 dockers/docker-bfn-sswsyncd-rpc/Dockerfile delete mode 100755 dockers/docker-bfn-sswsyncd/Dockerfile diff --git a/dockers/docker-bfn-sswsyncd-rpc/Dockerfile b/dockers/docker-bfn-sswsyncd-rpc/Dockerfile deleted file mode 100644 index 4d1b3e49bcda..000000000000 --- a/dockers/docker-bfn-sswsyncd-rpc/Dockerfile +++ /dev/null @@ -1,38 +0,0 @@ -FROM docker-base - -## Make apt-get non-interactive -ENV DEBIAN_FRONTEND=noninteractive - -## Pre-install the fundamental packages -RUN apt-get update \ - && apt-get -y install \ - net-tools - -COPY deps /deps -RUN dpkg_apt() { [ -f $1 ] && { dpkg -i $1 || apt-get -y install -f; } || return 1; }; \ - dpkg_apt /deps/python-tabulate_*.deb \ - && dpkg_apt /deps/applibs_*.deb \ - && dpkg_apt /deps/applibs-dev_*.deb \ - && dpkg_apt /deps/sx-complib_*.deb \ - && dpkg_apt /deps/sxd-libs_*.deb \ - && dpkg_apt /deps/sx-scew_*.deb \ - && dpkg_apt /deps/sx-examples_*.deb \ - && dpkg_apt /deps/sx-gen-utils_*.deb \ - && dpkg_apt /deps/python-sdk-api_*.deb \ - && dpkg_apt /deps/sx-libnl_*.deb \ - && dpkg_apt /deps/iproute2_*.deb \ - && dpkg_apt /deps/libsswsdk_*.deb \ - && dpkg_apt /deps/libthrift-0.9.3_*.deb \ - && dpkg_apt /deps/libthrift-dev_*.deb - -RUN dpkg_apt() { [ -f $1 ] && { dpkg -i $1 || apt-get -y install -f; } || return 1; }; \ - dpkg_apt /deps/mlnx-sai_*.deb \ - && dpkg_apt /deps/sswsyncd-saithrift_*.deb - -## Clean up -RUN apt-get clean -y ; apt-get autoclean -y ; apt-get autoremove -y ; rm -rf /deps - -ENTRYPOINT service rsyslog start \ - && mkdir -p /dev/sxdevs && ( [ -e /dev/sxdevs/sxcdev ] || mknod /dev/sxdevs/sxcdev c 231 193 ) \ - && service sswsyncd start \ - && /bin/bash diff --git a/dockers/docker-bfn-sswsyncd/Dockerfile b/dockers/docker-bfn-sswsyncd/Dockerfile deleted file mode 100755 index 9bb6c71e8729..000000000000 --- a/dockers/docker-bfn-sswsyncd/Dockerfile +++ /dev/null @@ -1,17 +0,0 @@ -FROM docker-base - -## Make apt-get non-interactive -ENV DEBIAN_FRONTEND=noninteractive - -RUN apt-get update - -## Pre-install the fundamental packages -RUN apt-get update \ - && apt-get -y install \ - net-tools - -COPY deps /deps - -ENTRYPOINT service rsyslog start \ - && sleep 5 && service sswsyncd start \ - && /bin/bash diff --git a/dockers/docker-orchagent/swssconfig.sh b/dockers/docker-orchagent/swssconfig.sh index bb1b91a319cf..84e8f560a822 100755 --- a/dockers/docker-orchagent/swssconfig.sh +++ b/dockers/docker-orchagent/swssconfig.sh @@ -27,7 +27,13 @@ fast_reboot HWSKU=`sonic-cfggen -d -v "DEVICE_METADATA['localhost']['hwsku']"` -SWSSCONFIG_ARGS="00-copp.config.json ports.json switch.json " +SWSSCONFIG_ARGS="00-copp.config.json " + +if [ "$HWSKU" != "montara" ] && [ "$HWSKU" != "mavericks" ] && [ "$HWSKU" != "OSW1800-48x6q" ] && [ "$HWSKU" != "INGRASYS-S9180-32X"]; then + SWSSCONFIG_ARGS+="ipinip.json " +fi + +SWSSCONFIG_ARGS+="ports.json switch.json " if [ "$HWSKU" == "Force10-S6000" ]; then SWSSCONFIG_ARGS+="td2.32ports.buffers.json td2.32ports.qos.json " @@ -42,10 +48,6 @@ elif [[ "$HWSKU" == "ACS-MSN27"* ]]; then SWSSCONFIG_ARGS+="msn27xx.32ports.buffers.json " fi -if [ "$HWSKU" != "montara" ] && [ "$HWSKU" != "mavericks" ] && [ "$HWSKU" != "OSW1800-48x6q" ] && [ "$HWSKU" != "INGRASYS-S9180-32X"]; then - SWSSCONFIG_ARGS+="ipinip.json " -fi - for file in $SWSSCONFIG_ARGS; do swssconfig /etc/swss/config.d/$file sleep 1 diff --git a/dockers/docker-saiserver-bfn/start.sh b/dockers/docker-saiserver-bfn/start.sh index 57ee5036ded3..16457d13e03a 100755 --- a/dockers/docker-saiserver-bfn/start.sh +++ b/dockers/docker-saiserver-bfn/start.sh @@ -1,16 +1,8 @@ #!/usr/bin/env bash -start_mlnx() -{ - [ -e /dev/sxdevs/sxcdev ] || ( mkdir -p /dev/sxdevs && mknod /dev/sxdevs/sxcdev c 231 193 ) -} - - rm -f /var/run/rsyslogd.pid supervisorctl start rsyslogd -start_mlnx - supervisorctl start saiserver From dd0eb647db65ea9f0057a78b8d7f29282ffb2224 Mon Sep 17 00:00:00 2001 From: kram Date: Fri, 16 Mar 2018 16:14:29 -0700 Subject: [PATCH 58/58] revert refpoint of swss-common --- src/sonic-swss-common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-swss-common b/src/sonic-swss-common index cbc0e1a858ca..283162b62d1d 160000 --- a/src/sonic-swss-common +++ b/src/sonic-swss-common @@ -1 +1 @@ -Subproject commit cbc0e1a858cad81835c457bb98abc28af86523db +Subproject commit 283162b62d1dda594a5962e9ad8b4f9b65bf65c3