From 5f16e9622f938b64a98e6bb1c2882742ab854821 Mon Sep 17 00:00:00 2001 From: xumia <59720581+xumia@users.noreply.github.com> Date: Tue, 30 Jun 2020 06:01:20 +0800 Subject: [PATCH 01/23] Add the test signing certificates for secure boot (#4866) * Add the test signing certificates for secure boot * Remove unnecessary ca key file * Regenerate the certificates to not expose the ca key --- build_image.sh | 10 +++- .../secureboot/test-certs/ca.cert | 32 ++++++++++++ .../secureboot/test-certs/signing.cert | 30 +++++++++++ .../secureboot/test-certs/signing.key | 51 +++++++++++++++++++ 4 files changed, 122 insertions(+), 1 deletion(-) create mode 100644 files/image_config/secureboot/test-certs/ca.cert create mode 100644 files/image_config/secureboot/test-certs/signing.cert create mode 100644 files/image_config/secureboot/test-certs/signing.key diff --git a/build_image.sh b/build_image.sh index 4fd9f7315a..2cd3d98fb8 100755 --- a/build_image.sh +++ b/build_image.sh @@ -150,7 +150,15 @@ elif [ "$IMAGE_TYPE" = "aboot" ]; then if [ "$SONIC_ENABLE_IMAGE_SIGNATURE" = "y" ]; then TARGET_CA_CERT="$TARGET_PATH/ca.cert" rm -f "$TARGET_CA_CERT" - [ -f "$CA_CERT" ] && cp "$CA_CERT" "$TARGET_CA_CERT" + + # If the ca certificate does not exist, the test certificate will be used to sign the image + if [ ! -f "$CA_CERT" ]; then + TEST_CERT_PATH=files/image_config/secureboot/test-certs + CA_CERT="${TEST_CERT_PATH}/ca.cert" + SIGNING_KEY="${TEST_CERT_PATH}/signing.key" + SIGNING_CERT="${TEST_CERT_PATH}/signing.cert" + fi + cp "$CA_CERT" "$TARGET_CA_CERT" ./scripts/sign_image.sh -i "$OUTPUT_ABOOT_IMAGE" -k "$SIGNING_KEY" -c "$SIGNING_CERT" -a "$TARGET_CA_CERT" fi else diff --git a/files/image_config/secureboot/test-certs/ca.cert b/files/image_config/secureboot/test-certs/ca.cert new file mode 100644 index 0000000000..9cf0586edd --- /dev/null +++ b/files/image_config/secureboot/test-certs/ca.cert @@ -0,0 +1,32 @@ +-----BEGIN CERTIFICATE----- +MIIFdTCCA12gAwIBAgIUL2kglpzjw8n7sLr41bLDrLU8CcswDQYJKoZIhvcNAQEL +BQAwSTELMAkGA1UEBhMCVVMxDTALBgNVBAgMBFRlc3QxDTALBgNVBAcMBFRlc3Qx +DTALBgNVBAoMBFRlc3QxDTALBgNVBAMMBFRlc3QwIBcNMjAwNjI5MDYyNzE4WhgP +MjEyMDA2MDUwNjI3MThaMEkxCzAJBgNVBAYTAlVTMQ0wCwYDVQQIDARUZXN0MQ0w +CwYDVQQHDARUZXN0MQ0wCwYDVQQKDARUZXN0MQ0wCwYDVQQDDARUZXN0MIICIjAN +BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA32NtDS/zojvq37VlzMQYUXY58OWZ +hrgGnuq5j5bUWZlRGxjiRyRjYgeTC+gCFsT0u3Mgat1Kwo1rsOLCf62KArOUssMR +xGWEdubvYlIInC4RyuTq0a7lLxQH1q+mwHPpJHQ3Iv7Vj8cwmtwM/uAru6uOy+YN +Dl3Y+VCtbJ/3OB5u4W7toAmfPfoO/JNOxYQAYMNqMwFfK7MMh8HPjm5hQ9j+K+Df +yAlePFgnp8v4o3SdYzzW7rkV+q7ZfGM4VlPnNHgS2wcbI5NoFgpe86k3JSF6aFSh +p+fEQss/Kz2JXrfvR7TbpS/HpeoPRvUF7kSgCVfaMPdoOOwGtVkmIPlTN1y5xpyu +LH/v62TmNp3NOlbQ4oxgIrYfaYDXTByuFSlXft6VcJg7bJvGL8J1QqU7A040jSPn +45GaLm9nJpl//ik/MjU+qau8O7lvmz/2OjIwEDElAYTDnLoYYDeax9vJjcEni5/s +xi/fc7IyHtOgOpb5+bLumvvBy7qCM0sRuFliXAAFzwK1zn1WxwUMBuMjZjioCNPW +zfJ9jrmbBB2KJk/hyJ6mAVSE/tTL2vJsgjB3RabfS5ECr/ZXZXbNb3FUiFea5oUe +XKkzC6oUGfUb63ZwQ1oSX1q4ECt/OecAmujL3ATLILrptko3FgURjwYUTtPn5DyL +gYnc6CvZ3Tl70DECAwEAAaNTMFEwHQYDVR0OBBYEFFSMKiWUTzg7rggKQ95BbgCR +ZCxeMB8GA1UdIwQYMBaAFFSMKiWUTzg7rggKQ95BbgCRZCxeMA8GA1UdEwEB/wQF +MAMBAf8wDQYJKoZIhvcNAQELBQADggIBAI3N1xeBqtSy5/aOBPM3MG6WTfWaIwA2 +G7axvE9HLmOZ2jbNaV/is5ZTclgVocdYmg77MhhIzK7smPehUpimAntsk94E/zFA +K9sol4tPzWi+aVzf0fvEkOk+4WdPUMWkgyqFoiZ4n+ARJdN6Ef0Dcoue3DFbYu+M +94yOUD1KSXMDhknIwTCAtnCMDiFCv2f++LYOPs71ttJWnBGGtdYEibsAkFI9gOQ6 +ianw12D5ZWaF88jQt83B+gxw2QYRfpvW7enD1N7+kBfZV9BXa9IjVQ4kxi/DkEFM +ib1WR8zCmhb3wRkD0PVI6OE7XLjCjvGIhdsd3r+qHlHyzHJAJuuGxrLoenAe7T/P +eJ52mNtKGwASd/mShQpM+EbkGKnxKAp3ZJRMemeMboFk6WnPRZ7VYddHeXN57aGl +Yfg43cYfGACOHNfbs2X7zzNuqxpj1oLpDOHBD8UnYhGNWqfHAzmEDkxrReE/uO9R ++7NP3FFFx908OS7vgBSaUsYA9WX1VsJsyZjC/njHIPwZvKBRTvyTYfskSey1JA/O +YMp7NTL+LxSthab3Zgpe7ziYe+lQ/PkTBpy2UB0ntnUj2AER75VH3S8TBdIzlzCp +45+/TXbLOm+PO6iCIh/gHviCy5ua+txgZeG+/1sGrlYT0Je04e/HpVA7+aRzZF4+ +yxGRZsO7Ztjz +-----END CERTIFICATE----- diff --git a/files/image_config/secureboot/test-certs/signing.cert b/files/image_config/secureboot/test-certs/signing.cert new file mode 100644 index 0000000000..91b544cc5e --- /dev/null +++ b/files/image_config/secureboot/test-certs/signing.cert @@ -0,0 +1,30 @@ +-----BEGIN CERTIFICATE----- +MIIFGzCCAwMCFEzTPYLASoyMuK7LFp0mFz/fWFKYMA0GCSqGSIb3DQEBCwUAMEkx +CzAJBgNVBAYTAlVTMQ0wCwYDVQQIDARUZXN0MQ0wCwYDVQQHDARUZXN0MQ0wCwYD +VQQKDARUZXN0MQ0wCwYDVQQDDARUZXN0MCAXDTIwMDYyOTA2MjcxOVoYDzIwNzAw +NjE3MDYyNzE5WjBJMQswCQYDVQQGEwJVUzENMAsGA1UECAwEVGVzdDENMAsGA1UE +BwwEVGVzdDENMAsGA1UECgwEVGVzdDENMAsGA1UEAwwEVGVzdDCCAiIwDQYJKoZI +hvcNAQEBBQADggIPADCCAgoCggIBAMl+lKW0Kjdy2xpXIrIr+0DZ+hWACR1Lp2By +5ovSqHXrpndPJrP/rtPwC0wOIry8iEHPrUc9oez+G9q+hMGcQR+O9un55huWoqlg +/KoCDuyP7QtraBzwQmihrnEtsWyF9KKFnEHTRgkMNqH+JKBWQQmfBouMq7QmZ0oL +IQ2zIt/3fJzBTr70WH3xIhrIujjAoy10dAxsg4CA49KREpj72lrb1IAEdFj57HCm +MYGA85qq6M+Qz97Zd9F4IoNrTg+7WLMRBRJEnsC20rfKQdEDIBPuwAMCC6j1Q9Jc +HIKu4StCVo693lCjPV4RhhiHd1Y1+TezX7UM7Wt2XEM/Z0gMZ2Z42p8ByfsxFtVO +QdsWoyrA79n6VlU0237AwgyAYdTopU5alErTrYwhwbcZNLb0mpLijGnf0jwWr4uu +7nbgozKVAMrpJZufPYhG5dG6lBOODcMpbkDfHi9yPcoGIbZYV41IGJhLaYejecry +B56vgd2jGU7bnIB3Mth3t+Vsx1y67EW/8IopmGwL2MyTV4Z5Hq59wnR53Z1hQLB6 +twTgPJjo+n39YTt/I6pkYzV0ptpJb6BS8NTvADoYw5TQy3mW/HR0LayRwkzB+8Ii +GDwC6k+IXcmHjeyov0OXeieFXwZMDPlc0yoCzZ1sywQNG8EDOSisu9R/zMW8sJjD +b+lItF9jAgMBAAEwDQYJKoZIhvcNAQELBQADggIBAJqb9dChpXaOCdHKtcKbTgkm +Sf2HRN8lA7gszDQMXvenog+YinFO72bNzrRcmA2zYcpwutBLLBqZ6BccuSKc6F4Z +6Hv609mBTEWL64VqeQlsqADGS1+gzQGQm2AoFqNGdqCzx2EfoyXKIbmg4bik0INF +jQN0YsXsULMa4DSV/Cif3H3++e7kEa1/JxoqndTasrP9/YFJup3+90F1Q3ib0wql +W4kUVKpFxx0Qyi/zn8vrDsM2NfOur9rD7k9gv8GaN8PshPIGj0rzrIGf8QebugJ3 +0NsOaqLsR4+8KGGjT6ckcNDun1ajrRfMyKoNtxdI8l8zl80mQQtsbvIO5hmhUMy9 +AW+8QzBzgc/TJAAHlElxOYHwypcsNGbkIVczUy48gp4DhQtfs1q8HqzTwHtK+HTN +JzeQJtDnpAJARiCXr67+QTwAVszefqVK8N2UntuTzOhhs8PdP1jVv5g6gQpFfgI8 +IyniS46+mTO+FXYCkk2Ner2Jr6p3r2pMAQPSr28TEr75H2gUVufYSBUgrVDwPlio +SEk6Iccg/2KgWXPCj2/LmGcJZqCc8Z8L8CbT1z+5plpp+WcMVRxgbH/FHSQBkMsw +P2SSOVjJEkSYV5I6bYA97BBFpjovZS+7k6NmW1Lj1n33awdMrm1UXQRDTSKXOzVu +U/rAEWO3JyUeTNCL37Ec +-----END CERTIFICATE----- diff --git a/files/image_config/secureboot/test-certs/signing.key b/files/image_config/secureboot/test-certs/signing.key new file mode 100644 index 0000000000..9c16e80641 --- /dev/null +++ b/files/image_config/secureboot/test-certs/signing.key @@ -0,0 +1,51 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIJKQIBAAKCAgEAyX6UpbQqN3LbGlcisiv7QNn6FYAJHUunYHLmi9Kodeumd08m +s/+u0/ALTA4ivLyIQc+tRz2h7P4b2r6EwZxBH4726fnmG5aiqWD8qgIO7I/tC2to +HPBCaKGucS2xbIX0ooWcQdNGCQw2of4koFZBCZ8Gi4yrtCZnSgshDbMi3/d8nMFO +vvRYffEiGsi6OMCjLXR0DGyDgIDj0pESmPvaWtvUgAR0WPnscKYxgYDzmqroz5DP +3tl30Xgig2tOD7tYsxEFEkSewLbSt8pB0QMgE+7AAwILqPVD0lwcgq7hK0JWjr3e +UKM9XhGGGId3VjX5N7NftQzta3ZcQz9nSAxnZnjanwHJ+zEW1U5B2xajKsDv2fpW +VTTbfsDCDIBh1OilTlqUStOtjCHBtxk0tvSakuKMad/SPBavi67uduCjMpUAyukl +m589iEbl0bqUE44NwyluQN8eL3I9ygYhtlhXjUgYmEtph6N5yvIHnq+B3aMZTtuc +gHcy2He35WzHXLrsRb/wiimYbAvYzJNXhnkern3CdHndnWFAsHq3BOA8mOj6ff1h +O38jqmRjNXSm2klvoFLw1O8AOhjDlNDLeZb8dHQtrJHCTMH7wiIYPALqT4hdyYeN +7Ki/Q5d6J4VfBkwM+VzTKgLNnWzLBA0bwQM5KKy71H/MxbywmMNv6Ui0X2MCAwEA +AQKCAgEAuMZ2hDpimHSgTlhnveItR3xdJMhEE3RkKkNT/hcRWwndnv2brWckKMCx +a25vFosBnPBYo8L2MgGZA5DA51dmNQ2CinAbP2N1CUSijzjR/MfDhjxZvmfpTlAu +SyWu1alF/J/v+kFHsVZc51LKvao7fBo0A1bdwpeREsp/5jNHIQGwaYOvtdcXK28s +akl21EJ7oVxwa1A7i2UnBtr4pggXZki/ZyIum8WcuHT/YxYgzs46LtZKeb8NbK7x +X3jQngacwaEy+FyrBGjjdZ1pm8V07jJ8LIX8sVUxe7/yeTjrziLIg5/ENkhsJ06E +nQvlOM7IGvdIJhyTwH9K/nQvP1f4nNP+3RQSc8ubP5QqGGnlryhOvvV7QG8Y+ZN4 +mV1FOoyqiZdxFs/6PxKJfmNDoma8oz3pGQ810OnxtCu2kcxT54WBJdKxcQFxSxjS +8YVRoakmU6noUTqw6BaG9QwQnbLytXckXQDQlxqGd4WbL1nlCxZF25SxRCX2/mHd +7BUpW6OfxL/pEOcUBV0HO/ELm51xWMaZyGfZPkQRpbnpGgfXojuOnxdfiUbqkHy/ +/dV98pfgT+qy4FXn/zeGLnh6Q/JPcCQp6QeyUbC9jHvrkVLwuA8ugg9ilGvMSX8Q +vmVNe9UjkNVywoeiB5/Dc5CzgmG9hdsf2r+5BZNG3GilwsCAArECggEBAOzNasRY +j6mB47FJsxJDW0I16dBugLcenFTO70UzLeTGgsREzba6/ItnsH9ZPRRxmQoKC5a6 +yK+63DZo9YCOit8lSxx6otUev4RpDhsmnrG7ILQzXb3BO2bqbP+Xm1CNWkaZxRSZ +HKLwXAvKp+YLMJ7qAZRe5+E4c5i+9NdJWAFMHcVTIUdnJ2bPC1lwhCqC9zeuMj+j +U7U0Rt9sgy9azExK4/O8pvcYFS8JCpw5Kot/c+5C6F91Zj437k8hoSZhVIJgsvTF +PnEE+pt84p9vcd1CHKWRbB4QU92JpniJk2ZjNC184niG5bPbfJJrQda0xFKwLD8G +HYgr7rrfz6mNWqkCggEBANnUYmouBTVmgjnjJkq+OaUuyHv0LvBXdr+4DhSIMe03 +mEenRBj4AA9J9XCg0WnzX21gvistO+rJ+lHCiQjaY18LCz1KpDKnnliTVrlXsa9Y +Zyd8yZou0oX29fsEwjS/o0lJv9T+RxAjMXMTaDvLeybUIioFKBEHqUxkiMFCFygY ++8UA/PGXZB5ysgOJ3W1JTcNCTixM15+ItsJRjnqGtfm77jvTyGHPuG4VlJfYQg2B +HfP7p19RSJhqzNPhPpioXs5DJj0nVvbSDC4/ukJV5GltI87csjup/naSgBzhXvfH +F/4CBQdKPCsQVv27je/OEGzzd6B2E4IoIz5ZPzzJHSsCggEAVCKD/bENkgdRU+tA +kYuXAAZRxbmNSAK7PrKrdqXBd5hEW+GqSXNUSV+U6RpWxk26N0PsbCh/J1i35ykR +mRSMKM6CSmMUOa6ME0qUNXdaSQGYlA3wD3x5U46VHZbLGyqt2YnG6ROhhg7qVVIy +p1xwcPXpi8LQlkfNYobuTROFDijyJurrVwhCipeji6qbetM/bOwadFveYPJq//T5 +Azk6fxzYsv/jPsWyuRx4RZtWD2xAT3Y8Q7Zdllue80Sakh1gvlYHH0p5bgR72gTc +LBOXnCpiLT1m8aOReJPwrsEKuwUiQ8ssV/Bt6qJgN1Geed+OJWbswZO1qG0bjA/7 +I13SyQKCAQAeLgbUnzupgmJYktgjUue5sxmj0tkOA5A4T8/jmFsSerlmdA5DR1j6 +xUx0JlPdUhLOnLC8WrAKf6Fm4oUJ7PgHmwgbndPSENcnfoJte3Dq0ly4Y9mquwH/ +/Y9nD+m4VTTSWp1xbSl7WuTnBLFUV4TghFOXbs92TJFwPB2WaQm8THnVeaWR81+z +uEBhrSA4nAdiHjWmfZ8CQ3bOxW3wG+nqh9ciAt2ob5cl6WeFAjlklZcIzr0Jv8FH +HMT0NijuDaXU/gi2QFUULVXysnGj7zKOSMjFSF6JVawj0Xheh/sYaUUxtCXuNKLR +dJoY3Xt01iAAeFsCqFlblyQK52KTkWmxAoIBAQCDFtaLIp+gJ4kKCmUT30abaXXe +tb0D9CnXT1EQSpKqio9Soad1a9PZ6IkJU0Dhks2mJWX6CHR3mWpmXR31aWM/iP+u +X+/amrHPhzxyFCmbo+Vb96ZuelFvdZ0x4l6eM+qd9SxF+SnSyfdtnwOThLI7bZFc +L6rbYlTFdH3j6nksITAW1lp1W59jtkYQVIBl8rpiwNfgRFBf5FE9PKDjbG2WHx3a +kv81Ok5z6PV4BarViZ6hV2tP4b96/TbrXn08J6M4Gcn7KOn7UfYSP/2p7sIE+pC4 +EMO3sAR6IUU/utmknwY0Ou/enuzsq3RvpA/8kE4ZdRBMLUQeZZ4yzX0pyfSz +-----END RSA PRIVATE KEY----- From ef994a176c394bb290c972bb99f03741d65a7365 Mon Sep 17 00:00:00 2001 From: arlakshm <55814491+arlakshm@users.noreply.github.com> Date: Tue, 30 Jun 2020 06:29:20 -0700 Subject: [PATCH 02/23] syslog changes Multi ASIC platforms (#4738) Add changes for syslog support for containers running in namespaces on multi ASIC platforms. On Multi ASIC platforms Rsyslog service is only running on the host. There is no rsyslog service running in each namespace. On multi ASIC platforms the rsyslog service on the host will be listening on the docker0 ip address instead of loopback address. The rsyslog.conf on the containers is modified to have omfwd target ip to be docker0 ipaddress instead of loopback ip Signed-off-by: Arvindsrinivasan Lakshmi Narasimhan --- files/build_templates/docker_image_ctl.j2 | 17 +++++ .../build_templates/sonic_debian_extension.j2 | 1 + files/image_config/rsyslog/rsyslog-config.sh | 21 ++++- .../rsyslog/rsyslog-container.conf.j2 | 76 +++++++++++++++++++ files/image_config/rsyslog/rsyslog.conf.j2 | 2 +- 5 files changed, 115 insertions(+), 2 deletions(-) create mode 100644 files/image_config/rsyslog/rsyslog-container.conf.j2 diff --git a/files/build_templates/docker_image_ctl.j2 b/files/build_templates/docker_image_ctl.j2 index 381480123f..0a04617959 100644 --- a/files/build_templates/docker_image_ctl.j2 +++ b/files/build_templates/docker_image_ctl.j2 @@ -27,6 +27,22 @@ link_namespace() { } {%- endif %} +function updateSyslogConf() +{ + # On multiNPU platforms, change the syslog target ip to docker0 ip to allow logs from containers + # running on the namespace to reach the rsyslog service running on the host + # Also update the container name + if [[ ($NUM_ASIC -gt 1) ]]; then + TARGET_IP=$(docker network inspect bridge --format={{ "'{{(index .IPAM.Config 0).Gateway}}'" }}) + CONTAINER_NAME="{{docker_container_name}}$DEV" + TMP_FILE="/tmp/rsyslog.$CONTAINER_NAME.conf" + + sonic-cfggen -t /usr/share/sonic/templates/rsyslog-container.conf.j2 -a "{\"target_ip\": \"$TARGET_IP\", \"container_name\": \"$CONTAINER_NAME\" }" > $TMP_FILE + docker cp $TMP_FILE {{docker_container_name}}$DEV:/etc/rsyslog.conf + rm -rf $TMP_FILE + fi +} + function getMountPoint() { echo $1 | python -c "import sys, json, os; mnts = [x for x in json.load(sys.stdin)[0]['Mounts'] if x['Destination'] == '/usr/share/sonic/hwsku']; print '' if len(mnts) == 0 else os.path.basename(mnts[0]['Source'])" 2>/dev/null @@ -68,6 +84,7 @@ function preStartAction() {%- else %} : # nothing {%- endif %} + updateSyslogConf } function postStartAction() diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 925998f0ae..737ce1271f 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -241,6 +241,7 @@ echo "warmboot-finalizer.service" | sudo tee -a $GENERATED_SERVICE_FILE sudo cp $IMAGE_CONFIGS/rsyslog/rsyslog-config.service $FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM sudo cp $IMAGE_CONFIGS/rsyslog/rsyslog-config.sh $FILESYSTEM_ROOT/usr/bin/ sudo cp $IMAGE_CONFIGS/rsyslog/rsyslog.conf.j2 $FILESYSTEM_ROOT_USR_SHARE_SONIC_TEMPLATES/ +sudo cp $IMAGE_CONFIGS/rsyslog/rsyslog-container.conf.j2 $FILESYSTEM_ROOT_USR_SHARE_SONIC_TEMPLATES/ sudo cp $IMAGE_CONFIGS/rsyslog/rsyslog.d/* $FILESYSTEM_ROOT/etc/rsyslog.d/ echo "rsyslog-config.service" | sudo tee -a $GENERATED_SERVICE_FILE diff --git a/files/image_config/rsyslog/rsyslog-config.sh b/files/image_config/rsyslog/rsyslog-config.sh index c8ba7b9945..26767d84fb 100755 --- a/files/image_config/rsyslog/rsyslog-config.sh +++ b/files/image_config/rsyslog/rsyslog-config.sh @@ -1,4 +1,23 @@ #!/bin/bash -sonic-cfggen -d -t /usr/share/sonic/templates/rsyslog.conf.j2 >/etc/rsyslog.conf +PLATFORM=`sonic-cfggen -H -v DEVICE_METADATA.localhost.platform` + +# Parse the device specific asic conf file, if it exists +ASIC_CONF=/usr/share/sonic/device/$PLATFORM/asic.conf +if [ -f "$ASIC_CONF" ]; then + source $ASIC_CONF +fi + +# On Multi NPU platforms we need to start the rsyslog server on the docker0 ip address +# for the syslogs from the containers in the namespaces to work. +# on Single NPU platforms we continue to use loopback adddres + +if [[ ($NUM_ASIC -gt 1) ]]; then + udp_server_ip=$(ip -o -4 addr list docker0 | awk '{print $4}' | cut -d/ -f1) +else + udp_server_ip=$(ip -o -4 addr list lo scope host | awk '{print $4}' | cut -d/ -f1) +fi + +sonic-cfggen -d -t /usr/share/sonic/templates/rsyslog.conf.j2 -a "{\"udp_server_ip\": \"$udp_server_ip\"}" >/etc/rsyslog.conf + systemctl restart rsyslog diff --git a/files/image_config/rsyslog/rsyslog-container.conf.j2 b/files/image_config/rsyslog/rsyslog-container.conf.j2 new file mode 100644 index 0000000000..d17fbb6767 --- /dev/null +++ b/files/image_config/rsyslog/rsyslog-container.conf.j2 @@ -0,0 +1,76 @@ +# +# /etc/rsyslog.conf Configuration file for rsyslog. +# +# For more information see +# /usr/share/doc/rsyslog-doc/html/rsyslog_conf.html + + +################# +#### MODULES #### +################# + +$ModLoad imuxsock # provides support for local system logging + +# +# Set a rate limit on messages from the container +# +$SystemLogRateLimitInterval 300 +$SystemLogRateLimitBurst 20000 + +#$ModLoad imklog # provides kernel logging support +#$ModLoad immark # provides --MARK-- message capability + +# provides UDP syslog reception +#$ModLoad imudp +#$UDPServerRun 514 + +# provides TCP syslog reception +#$ModLoad imtcp +#$InputTCPServerRun 514 + + +########################### +#### GLOBAL DIRECTIVES #### +########################### + +# Set remote syslog server +template (name="ForwardFormatInContainer" type="string" string="<%PRI%>%TIMESTAMP:::date-rfc3339% %HOSTNAME% {{container_name}}#%syslogtag%%msg:::sp-if-no-1st-sp%%msg%") +*.* action(type="omfwd" target="{{target_ip}}" port="514" protocol="udp" Template="ForwardFormatInContainer") + +# +# Use traditional timestamp format. +# To enable high precision timestamps, comment out the following line. +# +#$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat + +# Define a custom template +$template SONiCFileFormat,"%TIMESTAMP%.%timestamp:::date-subseconds% %HOSTNAME% %syslogseverity-text:::uppercase% {{container_name}}#%syslogtag%%msg:::sp-if-no-1st-sp%%msg:::drop-last-lf%\n" +$ActionFileDefaultTemplate SONiCFileFormat + +# +# Set the default permissions for all log files. +# +$FileOwner root +$FileGroup adm +$FileCreateMode 0640 +$DirCreateMode 0755 +$Umask 0022 + +# +# Where to place spool and state files +# +$WorkDirectory /var/spool/rsyslog + +# +# Include all config files in /etc/rsyslog.d/ +# +$IncludeConfig /etc/rsyslog.d/*.conf + +# +# Suppress duplicate messages and report "message repeated n times" +# +$RepeatedMsgReduction on + +############### +#### RULES #### +############### diff --git a/files/image_config/rsyslog/rsyslog.conf.j2 b/files/image_config/rsyslog/rsyslog.conf.j2 index fbf8bf2016..37410293a4 100644 --- a/files/image_config/rsyslog/rsyslog.conf.j2 +++ b/files/image_config/rsyslog/rsyslog.conf.j2 @@ -19,7 +19,7 @@ $ModLoad imklog # provides kernel logging support # provides UDP syslog reception $ModLoad imudp -$UDPServerAddress 127.0.0.1 # bind to localhost before udp server run +$UDPServerAddress {{udp_server_ip}} #bind to localhost before udp server run $UDPServerRun 514 # provides TCP syslog reception From 22bf545bb6d1285caee1a3fd620a55464b894c86 Mon Sep 17 00:00:00 2001 From: Volodymyr Boiko <66446128+vboykox@users.noreply.github.com> Date: Tue, 30 Jun 2020 19:07:37 +0300 Subject: [PATCH 03/23] [sonic-platform-common] Update submodule (#4871) * src/sonic-platform-common 82bbeab...42781ff (1): > [SfpBase] Fix key name typo in docstring (#99) Signed-off-by: Volodymyr Boyko --- src/sonic-platform-common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-platform-common b/src/sonic-platform-common index 82bbeabc59..42781ff904 160000 --- a/src/sonic-platform-common +++ b/src/sonic-platform-common @@ -1 +1 @@ -Subproject commit 82bbeabc59b78886b5cadffe0998c8fe67031343 +Subproject commit 42781ff90413efe2ff709908a5318c85ca67f058 From ba234abd2b6f0d3a7deb8073b6c4b349cec1a3e7 Mon Sep 17 00:00:00 2001 From: Kebo Liu Date: Tue, 30 Jun 2020 21:32:56 +0300 Subject: [PATCH 04/23] [mellanox]: Update SAI to 1.16.5 (#4873) 1. Upgrade SAI headers to v1.6.3 2. Fix traffic lost during FFB related to buffer config + optimize buffer config timing for FB 3. Add ACL fields BTH, IP flags 4. Add ACL infrastructure of different fields per ASIC type --- platform/mellanox/mlnx-sai.mk | 2 +- platform/mellanox/mlnx-sai/SAI-Implementation | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/mellanox/mlnx-sai.mk b/platform/mellanox/mlnx-sai.mk index ba954beb7a..a978926f33 100644 --- a/platform/mellanox/mlnx-sai.mk +++ b/platform/mellanox/mlnx-sai.mk @@ -1,6 +1,6 @@ # Mellanox SAI -MLNX_SAI_VERSION = SAIRel1.16.4.1-sai16 +MLNX_SAI_VERSION = SAIRel1.16.5-sai16 export MLNX_SAI_VERSION diff --git a/platform/mellanox/mlnx-sai/SAI-Implementation b/platform/mellanox/mlnx-sai/SAI-Implementation index b318bb380a..0ddcb4e6d1 160000 --- a/platform/mellanox/mlnx-sai/SAI-Implementation +++ b/platform/mellanox/mlnx-sai/SAI-Implementation @@ -1 +1 @@ -Subproject commit b318bb380ac13dba98c94b163fbe644ab7eb236e +Subproject commit 0ddcb4e6d12efdd5255529ed53cc785351e8b3b3 From 6e1ae359f32a6dfd568c5767df4567f531718edb Mon Sep 17 00:00:00 2001 From: judyjoseph <53951155+judyjoseph@users.noreply.github.com> Date: Tue, 30 Jun 2020 14:32:04 -0700 Subject: [PATCH 05/23] Support for connecting to DB in namespace via TCP port in multi-asic platform. (#4779) * Support for connecting to DB in namespace via IP:port ( using docker bridge network ) for applications in multi-asic platform. * Added the default IP as 127.0.0.1 if the IPaddress derivation from interface fails. Moved the localhost loopback IP binding logic into the supervisor.j2 file. --- .../docker-database/database_config.json.j2 | 2 +- .../docker-database/docker-database-init.sh | 19 ++++++++++++++++++- dockers/docker-database/supervisord.conf.j2 | 7 ++++++- 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/dockers/docker-database/database_config.json.j2 b/dockers/docker-database/database_config.json.j2 index 3383ec1611..6d116b5e1a 100644 --- a/dockers/docker-database/database_config.json.j2 +++ b/dockers/docker-database/database_config.json.j2 @@ -1,7 +1,7 @@ { "INSTANCES": { "redis":{ - "hostname" : "127.0.0.1", + "hostname" : "{{HOST_IP}}", "port" : 6379, "unix_socket_path" : "/var/run/redis{{NAMESPACE_ID}}/redis.sock", "persistence_for_warm_boot" : "yes" diff --git a/dockers/docker-database/docker-database-init.sh b/dockers/docker-database/docker-database-init.sh index 5dae34d8f6..645a7d9927 100755 --- a/dockers/docker-database/docker-database-init.sh +++ b/dockers/docker-database/docker-database-init.sh @@ -1,12 +1,29 @@ #!/usr/bin/env bash +# For linux host namespace, in both single and multi ASIC platform use the loopback interface +# For other namespaces, use eth0 interface which is connected to the docker0 bridge in the host. +if [[ $NAMESPACE_ID == "" ]] +then + INTFC=lo +else + INTFC=eth0 +fi + +# Get the ip address of the interface +# if the ip address was not retrieved correctly, put localhost(127.0.0.1) as the default. +host_ip=$(ip -4 -o addr show $INTFC | awk '{print $4}' | cut -d'/' -f1 | head -1) +if [[ $host_ip == "" ]] +then + host_ip=127.0.0.1 +fi + REDIS_DIR=/var/run/redis$NAMESPACE_ID mkdir -p $REDIS_DIR/sonic-db if [ -f /etc/sonic/database_config$NAMESPACE_ID.json ]; then cp /etc/sonic/database_config$NAMESPACE_ID.json $REDIS_DIR/sonic-db/database_config.json else - j2 /usr/share/sonic/templates/database_config.json.j2 > $REDIS_DIR/sonic-db/database_config.json + HOST_IP=$host_ip j2 /usr/share/sonic/templates/database_config.json.j2 > $REDIS_DIR/sonic-db/database_config.json fi mkdir -p /etc/supervisor/conf.d/ diff --git a/dockers/docker-database/supervisord.conf.j2 b/dockers/docker-database/supervisord.conf.j2 index 44268274cd..6d4557dab7 100644 --- a/dockers/docker-database/supervisord.conf.j2 +++ b/dockers/docker-database/supervisord.conf.j2 @@ -20,7 +20,12 @@ stderr_logfile=syslog {% if INSTANCES %} {% for redis_inst, redis_items in INSTANCES.iteritems() %} [program: {{ redis_inst }}] -command=/bin/bash -c "{ [[ -s /var/lib/{{ redis_inst }}/dump.rdb ]] || rm -f /var/lib/{{ redis_inst }}/dump.rdb; } && mkdir -p /var/lib/{{ redis_inst }} && exec /usr/bin/redis-server /etc/redis/redis.conf --port {{ redis_items['port'] }} --unixsocket {{ redis_items['unix_socket_path'] }} --pidfile /var/run/redis/{{ redis_inst }}.pid --dir /var/lib/{{ redis_inst }}" +{% if redis_items['hostname'] != '127.0.0.1' %} +{%- set LOOPBACK_IP = '127.0.0.1' -%} +{%- else -%} +{%- set LOOPBACK_IP = '' -%} +{%- endif -%} +command=/bin/bash -c "{ [[ -s /var/lib/{{ redis_inst }}/dump.rdb ]] || rm -f /var/lib/{{ redis_inst }}/dump.rdb; } && mkdir -p /var/lib/{{ redis_inst }} && exec /usr/bin/redis-server /etc/redis/redis.conf --bind {{ LOOPBACK_IP }} {{ redis_items['hostname'] }} --port {{ redis_items['port'] }} --unixsocket {{ redis_items['unix_socket_path'] }} --pidfile /var/run/redis/{{ redis_inst }}.pid --dir /var/lib/{{ redis_inst }}" priority=2 autostart=true autorestart=false From ed7fafce7741f4641d128f8c053eabfeaac7de80 Mon Sep 17 00:00:00 2001 From: Mahesh Maddikayala <10645050+smaheshm@users.noreply.github.com> Date: Tue, 30 Jun 2020 16:29:47 -0700 Subject: [PATCH 06/23] [sonic-sairedis] sonic-sairedis submodule update (#4847) * sonic-sairedis submodule update * Update BRCM SAI to 3.7.5.1 --- platform/broadcom/sai.mk | 8 ++++---- src/sonic-sairedis | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/platform/broadcom/sai.mk b/platform/broadcom/sai.mk index 572ae0a70f..8599e712a3 100644 --- a/platform/broadcom/sai.mk +++ b/platform/broadcom/sai.mk @@ -1,8 +1,8 @@ -BRCM_SAI = libsaibcm_3.7.4.2-2_amd64.deb -$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.7/libsaibcm_3.7.4.2-2_amd64.deb?sv=2015-04-05&sr=b&sig=sl819d71a%2BcgrDtOt%2BmywfSL9N2EQS58qMJFq0aKqo8%3D&se=2034-02-11T20%3A28%3A46Z&sp=r" -BRCM_SAI_DEV = libsaibcm-dev_3.7.4.2-2_amd64.deb +BRCM_SAI = libsaibcm_3.7.5.1_amd64.deb +$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.7/libsaibcm_3.7.5.1_amd64.deb?sv=2015-04-05&sr=b&sig=hZLFA8GbuY83MW9g2ggfe53ATx9riuyL1JYXIe1Bib4%3D&se=2034-03-04T00%3A08%3A23Z&sp=r" +BRCM_SAI_DEV = libsaibcm-dev_3.7.5.1_amd64.deb $(eval $(call add_derived_package,$(BRCM_SAI),$(BRCM_SAI_DEV))) -$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.7/libsaibcm-dev_3.7.4.2-2_amd64.deb?sv=2015-04-05&sr=b&sig=cvOpP0PWFVmBNeYLMkxyI4BFBQf1DopD32t%2B3AkJHRg%3D&se=2034-02-11T20%3A27%3A46Z&sp=r" +$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.7/libsaibcm-dev_3.7.5.1_amd64.deb?sv=2015-04-05&sr=b&sig=i5GcJ8ATr4NL5iLth6DrX8YXxe7ir5OsXN7fxJISvCE%3D&se=2034-03-04T00%3A09%3A48Z&sp=r" SONIC_ONLINE_DEBS += $(BRCM_SAI) $(BRCM_SAI_DEV)_DEPENDS += $(BRCM_SAI) diff --git a/src/sonic-sairedis b/src/sonic-sairedis index 322dd01db4..ef72159552 160000 --- a/src/sonic-sairedis +++ b/src/sonic-sairedis @@ -1 +1 @@ -Subproject commit 322dd01db434d00394898d4d1ac34433e95447cd +Subproject commit ef721595520d827277610d11e24082934afc4df8 From 218714441b35f9188aea1d204f71de4d12c75967 Mon Sep 17 00:00:00 2001 From: Akhilesh Samineni <47657796+AkhileshSamineni@users.noreply.github.com> Date: Wed, 1 Jul 2020 15:22:52 +0530 Subject: [PATCH 07/23] [docker-nat]: Updated the NAT iptables patch for 4.19 buster (#4843) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Updated the NAT iptables patch for 4.19 buster Depends on PR : Azure/sonic-linux-kernel#147 1 Known issue: With both NAT patch files for 4.19 buster kernel, seeing 1 display issue in iptables like explained below On Docker NAT, iptables supported version is 1.6.0 and on base OS it’s 1.8.2. So seeing an display issue of which fullcone option is not showing in version 1.8.2 iptables output and no issues in functionality. Display issue – For example of comparsion: NAT Docker: root@sonic:/home/admin# docker exec -it nat bash root@sonic:/# iptables -t nat -nvL Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 0 0 DNAT all -- * * 0.0.0.0/0 0.0.0.0/0 to:1.1.1.1 fullcone Chain INPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination Chain OUTPUT (policy ACCEPT 30 packets, 2749 bytes) pkts bytes target prot opt in out source destination Chain POSTROUTING (policy ACCEPT 30 packets, 2749 bytes) pkts bytes target prot opt in out source destination root@sonic:/# Base OS: root@sonic:/home/admin# iptables-legacy -t nat -nvL Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 1 36 DNAT all -- * * 0.0.0.0/0 0.0.0.0/0 to:1.1.1.1 Chain INPUT (policy ACCEPT 1 packets, 36 bytes) pkts bytes target prot opt in out source destination Chain OUTPUT (policy ACCEPT 41 packets, 3572 bytes) pkts bytes target prot opt in out source destination Chain POSTROUTING (policy ACCEPT 41 packets, 3572 bytes) pkts bytes target prot opt in out source destination root@sonic:/home/admin# To fix this issue, iptables need to update from 1.6.0 to 1.8.2 version and have to update the NAT docker from stretch to buster. Will raise a new PR with this. Signed-off-by: Akhilesh Samineni akhilesh.samineni@broadcom.com Signed-off-by: Akhilesh Samineni --- .../0001-Passing-fullcone-option-for-SNAT-and-DNAT.patch | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/iptables/patch/0001-Passing-fullcone-option-for-SNAT-and-DNAT.patch b/src/iptables/patch/0001-Passing-fullcone-option-for-SNAT-and-DNAT.patch index f7fba85a27..528ce8edea 100644 --- a/src/iptables/patch/0001-Passing-fullcone-option-for-SNAT-and-DNAT.patch +++ b/src/iptables/patch/0001-Passing-fullcone-option-for-SNAT-and-DNAT.patch @@ -19,7 +19,7 @@ index a14d16f..4bfab98 100644 +/* Temporarily defining here, need to be picked up from the + * new kernel header linux/netfilter/nf_nat.h */ -+#define NF_NAT_RANGE_FULLCONE (1 << 5) ++#define NF_NAT_RANGE_FULLCONE (1 << 6) + enum { O_TO_DEST = 0, @@ -106,7 +106,7 @@ index b7b5fc7..88ff650 100644 +/* Temporarily defining here, need to be picked up from the + * new kernel header linux/netfilter/nf_nat.h */ -+#define NF_NAT_RANGE_FULLCONE (1 << 5) ++#define NF_NAT_RANGE_FULLCONE (1 << 6) + enum { O_TO_PORTS = 0, @@ -181,7 +181,7 @@ index e92d811..9634ba9 100644 +/* Temporarily defining here, need to be picked up from the + * new kernel header linux/netfilter/nf_nat.h */ -+#define NF_NAT_RANGE_FULLCONE (1 << 5) ++#define NF_NAT_RANGE_FULLCONE (1 << 6) + enum { O_TO_SRC = 0, From 243268f11c202a5f2140c5312136b8fd1ceb8e68 Mon Sep 17 00:00:00 2001 From: Mahesh Maddikayala <10645050+smaheshm@users.noreply.github.com> Date: Wed, 1 Jul 2020 09:08:21 -0700 Subject: [PATCH 08/23] Fix in libsaibcm for high CPU utilization of syncd (#4874) --- platform/broadcom/sai.mk | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/platform/broadcom/sai.mk b/platform/broadcom/sai.mk index 8599e712a3..bda1231bf2 100644 --- a/platform/broadcom/sai.mk +++ b/platform/broadcom/sai.mk @@ -1,8 +1,8 @@ -BRCM_SAI = libsaibcm_3.7.5.1_amd64.deb -$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.7/libsaibcm_3.7.5.1_amd64.deb?sv=2015-04-05&sr=b&sig=hZLFA8GbuY83MW9g2ggfe53ATx9riuyL1JYXIe1Bib4%3D&se=2034-03-04T00%3A08%3A23Z&sp=r" -BRCM_SAI_DEV = libsaibcm-dev_3.7.5.1_amd64.deb +BRCM_SAI = libsaibcm_3.7.5.1-1_amd64.deb +$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.7/master/libsaibcm_3.7.5.1-1_amd64.deb?sv=2015-04-05&sr=b&sig=vSaGIDz2fHBtQXmwJ8OrulAF1N%2Bwk%2B51CkqwNiZFx6I%3D&se=2034-03-10T00%3A45%3A39Z&sp=r" +BRCM_SAI_DEV = libsaibcm-dev_3.7.5.1-1_amd64.deb $(eval $(call add_derived_package,$(BRCM_SAI),$(BRCM_SAI_DEV))) -$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.7/libsaibcm-dev_3.7.5.1_amd64.deb?sv=2015-04-05&sr=b&sig=i5GcJ8ATr4NL5iLth6DrX8YXxe7ir5OsXN7fxJISvCE%3D&se=2034-03-04T00%3A09%3A48Z&sp=r" +$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.7/master/libsaibcm-dev_3.7.5.1-1_amd64.deb?sv=2015-04-05&sr=b&sig=XpczZg8q3b2z3754wXdc4faOXOFofdlydJKEQaed01o%3D&se=2034-03-10T00%3A46%3A38Z&sp=r" SONIC_ONLINE_DEBS += $(BRCM_SAI) $(BRCM_SAI_DEV)_DEPENDS += $(BRCM_SAI) From e66cb47ac1096bf1e37dc77a52f02426ab833cd9 Mon Sep 17 00:00:00 2001 From: abdosi <58047199+abdosi@users.noreply.github.com> Date: Wed, 1 Jul 2020 15:58:53 -0700 Subject: [PATCH 09/23] [sonic-buildimage] Changes to make network specific sysctl common for both host and docker namespace (#4838) * [sonic-buildimage] Changes to make network specific sysctl common for both host and docker namespace (in multi-npu). This change is triggered with issue found in multi-npu platforms where in docker namespace net.ipv6.conf.all.forwarding was 0 (should be 1) because of which RS/RA message were triggered and link-local router were learnt. Beside this there were some other sysctl.net.ipv6* params whose value in docker namespace is not same as host namespace. So to make we are always in sync in host and docker namespace created common file that list all sysctl.net.* params and used both by host and docker namespace. Any change will get applied to both namespace. Signed-off-by: Abhishek Dosi * Address Review Comments and made sure to invoke augtool only one and do string concatenation of all set commands * Address Review Comments. --- build_debian.sh | 57 +++++------------------ dockers/docker-database/Dockerfile.j2 | 1 + files/build_templates/docker_image_ctl.j2 | 2 +- files/image_config/sysctl/sysctl-net.conf | 39 ++++++++++++++++ rules/docker-database.mk | 2 +- rules/scripts.mk | 8 ++-- 6 files changed, 58 insertions(+), 51 deletions(-) create mode 100644 files/image_config/sysctl/sysctl-net.conf diff --git a/build_debian.sh b/build_debian.sh index 550585c176..be973ea4a8 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -389,61 +389,26 @@ rm /files/lib/systemd/system/rsyslog.service/Service/ExecStart/arguments set /files/lib/systemd/system/rsyslog.service/Service/ExecStart/arguments/1 -n " -## Config sysctl sudo mkdir -p $FILESYSTEM_ROOT/var/core + +# Config sysctl sudo augtool --autosave " set /files/etc/sysctl.conf/kernel.core_pattern '|/usr/bin/coredump-compress %e %t %p' - set /files/etc/sysctl.conf/kernel.softlockup_panic 1 set /files/etc/sysctl.conf/kernel.panic 10 set /files/etc/sysctl.conf/vm.panic_on_oom 2 set /files/etc/sysctl.conf/fs.suid_dumpable 2 +" -r $FILESYSTEM_ROOT -set /files/etc/sysctl.conf/net.ipv4.conf.default.forwarding 1 -set /files/etc/sysctl.conf/net.ipv4.conf.all.forwarding 1 -set /files/etc/sysctl.conf/net.ipv4.conf.eth0.forwarding 0 - -set /files/etc/sysctl.conf/net.ipv4.conf.default.arp_accept 0 -set /files/etc/sysctl.conf/net.ipv4.conf.default.arp_announce 0 -set /files/etc/sysctl.conf/net.ipv4.conf.default.arp_filter 0 -set /files/etc/sysctl.conf/net.ipv4.conf.default.arp_notify 0 -set /files/etc/sysctl.conf/net.ipv4.conf.default.arp_ignore 0 -set /files/etc/sysctl.conf/net.ipv4.conf.all.arp_accept 0 -set /files/etc/sysctl.conf/net.ipv4.conf.all.arp_announce 1 -set /files/etc/sysctl.conf/net.ipv4.conf.all.arp_filter 0 -set /files/etc/sysctl.conf/net.ipv4.conf.all.arp_notify 1 -set /files/etc/sysctl.conf/net.ipv4.conf.all.arp_ignore 2 - -set /files/etc/sysctl.conf/net.ipv4.neigh.default.base_reachable_time_ms 1800000 -set /files/etc/sysctl.conf/net.ipv6.neigh.default.base_reachable_time_ms 1800000 -set /files/etc/sysctl.conf/net.ipv4.neigh.default.gc_thresh1 1024 -set /files/etc/sysctl.conf/net.ipv6.neigh.default.gc_thresh1 1024 -set /files/etc/sysctl.conf/net.ipv4.neigh.default.gc_thresh2 2048 -set /files/etc/sysctl.conf/net.ipv6.neigh.default.gc_thresh2 2048 -set /files/etc/sysctl.conf/net.ipv4.neigh.default.gc_thresh3 4096 -set /files/etc/sysctl.conf/net.ipv6.neigh.default.gc_thresh3 4096 - -set /files/etc/sysctl.conf/net.ipv6.conf.default.forwarding 1 -set /files/etc/sysctl.conf/net.ipv6.conf.all.forwarding 1 -set /files/etc/sysctl.conf/net.ipv6.conf.eth0.forwarding 0 - -set /files/etc/sysctl.conf/net.ipv6.conf.default.accept_dad 0 -set /files/etc/sysctl.conf/net.ipv6.conf.all.accept_dad 0 -set /files/etc/sysctl.conf/net.ipv6.conf.eth0.accept_dad 0 - -set /files/etc/sysctl.conf/net.ipv6.conf.default.keep_addr_on_down 1 -set /files/etc/sysctl.conf/net.ipv6.conf.all.keep_addr_on_down 1 -set /files/etc/sysctl.conf/net.ipv6.conf.eth0.keep_addr_on_down 1 - -set /files/etc/sysctl.conf/net.ipv4.tcp_l3mdev_accept 1 -set /files/etc/sysctl.conf/net.ipv4.udp_l3mdev_accept 1 - -set /files/etc/sysctl.conf/net.core.rmem_max 2097152 -set /files/etc/sysctl.conf/net.core.wmem_max 2097152 - -set /files/etc/sysctl.conf/net.core.somaxconn 512 +sysctl_net_cmd_string="" +while read line; do + [[ "$line" =~ ^#.*$ ]] && continue + sysctl_net_conf_key=`echo $line | awk -F '=' '{print $1}'` + sysctl_net_conf_value=`echo $line | awk -F '=' '{print $2}'` + sysctl_net_cmd_string=$sysctl_net_cmd_string"set /files/etc/sysctl.conf/$sysctl_net_conf_key $sysctl_net_conf_value"$'\n' +done < files/image_config/sysctl/sysctl-net.conf -" -r $FILESYSTEM_ROOT +sudo augtool --autosave "$sysctl_net_cmd_string" -r $FILESYSTEM_ROOT ## docker Python API package is needed by Ansible docker module sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install 'docker==4.1.0' diff --git a/dockers/docker-database/Dockerfile.j2 b/dockers/docker-database/Dockerfile.j2 index e14be96e85..cf62d6868d 100644 --- a/dockers/docker-database/Dockerfile.j2 +++ b/dockers/docker-database/Dockerfile.j2 @@ -40,6 +40,7 @@ COPY ["docker-database-init.sh", "/usr/local/bin/"] COPY ["database_config.json.j2", "/usr/share/sonic/templates/"] COPY ["database_global.json.j2", "/usr/share/sonic/templates/"] COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] +COPY ["files/sysctl-net.conf", "/etc/sysctl.d/"] COPY ["critical_processes", "/etc/supervisor"] ENTRYPOINT ["/usr/local/bin/docker-database-init.sh"] diff --git a/files/build_templates/docker_image_ctl.j2 b/files/build_templates/docker_image_ctl.j2 index 0a04617959..2ddc18a8ce 100644 --- a/files/build_templates/docker_image_ctl.j2 +++ b/files/build_templates/docker_image_ctl.j2 @@ -91,7 +91,7 @@ function postStartAction() { {%- if docker_container_name == "database" %} if [ "$DEV" ]; then - docker exec -i database$DEV sysctl -w net.ipv6.conf.all.disable_ipv6=0 + docker exec -i database$DEV sysctl --system -e link_namespace $DEV fi diff --git a/files/image_config/sysctl/sysctl-net.conf b/files/image_config/sysctl/sysctl-net.conf new file mode 100644 index 0000000000..62fda3a8ca --- /dev/null +++ b/files/image_config/sysctl/sysctl-net.conf @@ -0,0 +1,39 @@ +# All the sysctl for ipv4/ipv6 network. +# Same will be used in host or docker namespace +# It should be provided as key=value format for parsing +net.ipv6.conf.all.disable_ipv6=0 +net.ipv4.conf.default.forwarding=1 +net.ipv4.conf.all.forwarding=1 +net.ipv4.conf.eth0.forwarding=0 +net.ipv4.conf.default.arp_accept=0 +net.ipv4.conf.default.arp_announce=0 +net.ipv4.conf.default.arp_filter=0 +net.ipv4.conf.default.arp_notify=0 +net.ipv4.conf.default.arp_ignore=0 +net.ipv4.conf.all.arp_accept=0 +net.ipv4.conf.all.arp_announce=1 +net.ipv4.conf.all.arp_filter=0 +net.ipv4.conf.all.arp_notify=1 +net.ipv4.conf.all.arp_ignore=2 +net.ipv4.neigh.default.base_reachable_time_ms=1800000 +net.ipv6.neigh.default.base_reachable_time_ms=1800000 +net.ipv4.neigh.default.gc_thresh1=1024 +net.ipv6.neigh.default.gc_thresh1=1024 +net.ipv4.neigh.default.gc_thresh2=2048 +net.ipv6.neigh.default.gc_thresh2=2048 +net.ipv4.neigh.default.gc_thresh3=4096 +net.ipv6.neigh.default.gc_thresh3=4096 +net.ipv6.conf.default.forwarding=1 +net.ipv6.conf.all.forwarding=1 +net.ipv6.conf.eth0.forwarding=0 +net.ipv6.conf.default.accept_dad=0 +net.ipv6.conf.all.accept_dad=0 +net.ipv6.conf.eth0.accept_dad=0 +net.ipv6.conf.default.keep_addr_on_down=1 +net.ipv6.conf.all.keep_addr_on_down=1 +net.ipv6.conf.eth0.keep_addr_on_down=1 +net.ipv4.tcp_l3mdev_accept=1 +net.ipv4.udp_l3mdev_accept=1 +net.core.rmem_max=2097152 +net.core.wmem_max=2097152 +net.core.somaxconn=512 diff --git a/rules/docker-database.mk b/rules/docker-database.mk index 8062c3b147..7cfd8f0bf2 100644 --- a/rules/docker-database.mk +++ b/rules/docker-database.mk @@ -24,4 +24,4 @@ $(DOCKER_DATABASE)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro $(DOCKER_DATABASE)_BASE_IMAGE_FILES += redis-cli:/usr/bin/redis-cli $(DOCKER_DATABASE)_BASE_IMAGE_FILES += monit_database:/etc/monit/conf.d -$(DOCKER_DATABASE)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) +$(DOCKER_DATABASE)_FILES += $(SYSCTL_NET_CONFIG) $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) diff --git a/rules/scripts.mk b/rules/scripts.mk index 8c6d0324fc..b3ed0cab95 100644 --- a/rules/scripts.mk +++ b/rules/scripts.mk @@ -14,10 +14,12 @@ $(QOS_CONFIG_TEMPLATE)_PATH = files/build_templates SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT = supervisor-proc-exit-listener $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT)_PATH = files/scripts +SYSCTL_NET_CONFIG = sysctl-net.conf +$(SYSCTL_NET_CONFIG)_PATH = files/image_config/sysctl + SONIC_COPY_FILES += $(CONFIGDB_LOAD_SCRIPT) \ $(ARP_UPDATE_SCRIPT) \ $(BUFFERS_CONFIG_TEMPLATE) \ $(QOS_CONFIG_TEMPLATE) \ - $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) - - + $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) \ + $(SYSCTL_NET_CONFIG) From 2e0aa4f1442327a358f2f6a85c2325ffc5f2f72b Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Thu, 2 Jul 2020 00:22:58 -0700 Subject: [PATCH 10/23] [pfx_filter]: Add a prefix mask by default in pfx_filter, when there is no one (#4860) If some table with a list of tuples (interface name, ip prefix) has ip prefixes without a mask length, it will cause issues in SONiC. For example quagga and frr will treat ipv4 address without a mask, so "10.20.30.40" address will be treated as "10.0.0.0/8", which is dangerous. The fix here is that when pfx_filter get a tuple (interface name, ip prefix), where the ip prefix doesn't have prefix mask length, add a mask by default: "/32 for ipv4 addresses, /128 for ipv6 addresses". Co-authored-by: Pavel Shirshov --- src/sonic-bgpcfgd/app/template.py | 12 +- src/sonic-bgpcfgd/tests/test_pfx_filter.py | 139 ++++++++++++++++++ src/sonic-config-engine/sonic-cfggen | 12 +- .../tests/data/pfx_filter/param_1.json | 12 ++ .../tests/data/pfx_filter/result_1.txt | 5 + .../tests/data/pfx_filter/tmpl_1.txt.j2 | 3 + .../tests/test_cfggen_pfx_filter.py | 15 ++ 7 files changed, 196 insertions(+), 2 deletions(-) create mode 100644 src/sonic-bgpcfgd/tests/test_pfx_filter.py create mode 100644 src/sonic-config-engine/tests/data/pfx_filter/param_1.json create mode 100644 src/sonic-config-engine/tests/data/pfx_filter/result_1.txt create mode 100644 src/sonic-config-engine/tests/data/pfx_filter/tmpl_1.txt.j2 create mode 100644 src/sonic-config-engine/tests/test_cfggen_pfx_filter.py diff --git a/src/sonic-bgpcfgd/app/template.py b/src/sonic-bgpcfgd/app/template.py index 5c8a4ed810..e880738811 100644 --- a/src/sonic-bgpcfgd/app/template.py +++ b/src/sonic-bgpcfgd/app/template.py @@ -4,6 +4,7 @@ import jinja2 import netaddr +from .log import log_err class TemplateFabric(object): """ Fabric for rendering jinja2 templates """ @@ -94,5 +95,14 @@ def pfx_filter(value): for key, val in value.items(): if not isinstance(key, tuple): continue - table[key] = val + intf, ip_address = key + if '/' not in ip_address: + if TemplateFabric.is_ipv4(ip_address): + table[(intf, "%s/32" % ip_address)] = val + elif TemplateFabric.is_ipv6(ip_address): + table[(intf, "%s/128" % ip_address)] = val + else: + log_err("'%s' is invalid ip address" % ip_address) + else: + table[key] = val return table \ No newline at end of file diff --git a/src/sonic-bgpcfgd/tests/test_pfx_filter.py b/src/sonic-bgpcfgd/tests/test_pfx_filter.py new file mode 100644 index 0000000000..3eebd3951f --- /dev/null +++ b/src/sonic-bgpcfgd/tests/test_pfx_filter.py @@ -0,0 +1,139 @@ +from app.template import TemplateFabric +from collections import OrderedDict +import pytest + + +def test_pfx_filter_none(): + res = TemplateFabric.pfx_filter(None) + assert isinstance(res, OrderedDict) and len(res) == 0 + +def test_pfx_filter_empty_tuple(): + res = TemplateFabric.pfx_filter(()) + assert isinstance(res, OrderedDict) and len(res) == 0 + +def test_pfx_filter_empty_list(): + res = TemplateFabric.pfx_filter([]) + assert isinstance(res, OrderedDict) and len(res) == 0 + +def test_pfx_filter_empty_dict(): + res = TemplateFabric.pfx_filter({}) + assert isinstance(res, OrderedDict) and len(res) == 0 + +def test_pfx_filter_strings(): + src = { + 'Loopback0': {}, + 'Loopback1': {}, + } + expected = OrderedDict([]) + res = TemplateFabric.pfx_filter(src) + assert res == expected + +def test_pfx_filter_mixed_keys(): + src = { + 'Loopback0': {}, + ('Loopback0', '11.11.11.11/32'): {}, + 'Loopback1': {}, + ('Loopback1', '55.55.55.55/32'): {}, + } + expected = OrderedDict( + [ + (('Loopback1', '55.55.55.55/32'), {}), + (('Loopback0', '11.11.11.11/32'), {}), + ] + ) + res = TemplateFabric.pfx_filter(src) + assert res == expected + + +def test_pfx_filter_pfx_v4_w_mask(): + src = { + ('Loopback0', '11.11.11.11/32'): {}, + ('Loopback1', '55.55.55.55/32'): {}, + } + expected = OrderedDict( + [ + (('Loopback1', '55.55.55.55/32'), {}), + (('Loopback0', '11.11.11.11/32'), {}), + ] + ) + res = TemplateFabric.pfx_filter(src) + assert res == expected + +def test_pfx_filter_pfx_v6_w_mask(): + src = { + ('Loopback0', 'fc00::/128'): {}, + ('Loopback1', 'fc00::1/128'): {}, + } + expected = OrderedDict( + [ + (('Loopback0', 'fc00::/128'), {}), + (('Loopback1', 'fc00::1/128'), {}), + ] + ) + res = TemplateFabric.pfx_filter(src) + assert res == expected + +def test_pfx_filter_pfx_v4_no_mask(): + src = { + ('Loopback0', '11.11.11.11'): {}, + ('Loopback1', '55.55.55.55'): {}, + } + expected = OrderedDict( + [ + (('Loopback1', '55.55.55.55/32'), {}), + (('Loopback0', '11.11.11.11/32'), {}), + ] + ) + res = TemplateFabric.pfx_filter(src) + assert res == expected + +def test_pfx_filter_pfx_v6_no_mask(): + src = { + ('Loopback0', 'fc00::'): {}, + ('Loopback1', 'fc00::1'): {}, + } + expected = OrderedDict( + [ + (('Loopback0', 'fc00::/128'), {}), + (('Loopback1', 'fc00::1/128'), {}), + ] + ) + res = TemplateFabric.pfx_filter(src) + assert res == expected + + +def test_pfx_filter_pfx_comprehensive(): + src = { + 'Loopback0': {}, + ('Loopback0', 'fc00::'): {}, + 'Loopback1': {}, + ('Loopback1', 'fc00::1/128'): {}, + ('Loopback2', '11.11.11.11/32'): {}, + ('Loopback3', '55.55.55.55'): {}, + 'Loopback2': {}, + 'Loopback3': {}, + ('Loopback5', '22.22.22.1/24'): {}, + ('Loopback6', 'fc00::55/64'): {}, + } + expected = OrderedDict( + [ + (('Loopback1', 'fc00::1/128'), {}), + (('Loopback3', '55.55.55.55/32'), {}), + (('Loopback6', 'fc00::55/64'), {}), + (('Loopback2', '11.11.11.11/32'), {}), + (('Loopback0', 'fc00::/128'), {}), + (('Loopback5', '22.22.22.1/24'), {}), + ] + ) + res = TemplateFabric.pfx_filter(src) + assert res == expected + +@pytest.fixture +def test_pfx_filter_wrong_ip(caplog): + src = { + ('Loopback0', 'wrong_ip'): {}, + } + res = TemplateFabric.pfx_filter(src) + assert "'wrong_ip' is invalid ip address" in caplog.text + assert isinstance(res, OrderedDict) and len(res) == 0 + diff --git a/src/sonic-config-engine/sonic-cfggen b/src/sonic-config-engine/sonic-cfggen index c0f61d8a95..8528f828c8 100755 --- a/src/sonic-config-engine/sonic-cfggen +++ b/src/sonic-config-engine/sonic-cfggen @@ -113,7 +113,17 @@ def pfx_filter(value): for key,val in value.items(): if not isinstance(key, tuple): continue - table[key] = val + intf, ip_address = key + if '/' not in ip_address: + if is_ipv4(ip_address): + new_ip_address = "%s/32" % ip_address + elif is_ipv6(ip_address): + new_ip_address = "%s/128" % ip_address + else: + raise ValueError("'%s' is invalid ip address" % ip_address) + table[(intf, new_ip_address)] = val + else: + table[key] = val return table def ip_network(value): diff --git a/src/sonic-config-engine/tests/data/pfx_filter/param_1.json b/src/sonic-config-engine/tests/data/pfx_filter/param_1.json new file mode 100644 index 0000000000..ce6cd21886 --- /dev/null +++ b/src/sonic-config-engine/tests/data/pfx_filter/param_1.json @@ -0,0 +1,12 @@ +{ + "VLAN_INTERFACE": { + "Vlan1": {}, + "Vlan1|1.1.1.1/32": {}, + "Vlan2": {}, + "Vlan2|2.2.2.2": {}, + "Vlan3": {}, + "Vlan3|fc00::1": {}, + "Vlan4": {}, + "Vlan4|fc00::2/64": {} + } +} diff --git a/src/sonic-config-engine/tests/data/pfx_filter/result_1.txt b/src/sonic-config-engine/tests/data/pfx_filter/result_1.txt new file mode 100644 index 0000000000..d8ea7d3042 --- /dev/null +++ b/src/sonic-config-engine/tests/data/pfx_filter/result_1.txt @@ -0,0 +1,5 @@ +"Vlan1"="1.1.1.1/32" +"Vlan2"="2.2.2.2/32" +"Vlan3"="fc00::1/128" +"Vlan4"="fc00::2/64" + diff --git a/src/sonic-config-engine/tests/data/pfx_filter/tmpl_1.txt.j2 b/src/sonic-config-engine/tests/data/pfx_filter/tmpl_1.txt.j2 new file mode 100644 index 0000000000..2612fe4a29 --- /dev/null +++ b/src/sonic-config-engine/tests/data/pfx_filter/tmpl_1.txt.j2 @@ -0,0 +1,3 @@ +{% for intf, addr in VLAN_INTERFACE|pfx_filter %} +"{{ intf }}"="{{ addr }}" +{% endfor %} diff --git a/src/sonic-config-engine/tests/test_cfggen_pfx_filter.py b/src/sonic-config-engine/tests/test_cfggen_pfx_filter.py new file mode 100644 index 0000000000..8ffd72907b --- /dev/null +++ b/src/sonic-config-engine/tests/test_cfggen_pfx_filter.py @@ -0,0 +1,15 @@ +from unittest import TestCase +import subprocess + +class TestPfxFilter(TestCase): + def test_comprehensive(self): + # Generate output + data_dir = "tests/data/pfx_filter" + cmd = "./sonic-cfggen -j %s/param_1.json -t %s/tmpl_1.txt.j2 > /tmp/result_1.txt" % (data_dir, data_dir) + subprocess.check_output(cmd, shell=True) + # Compare outputs + cmd = "diff -u tests/data/pfx_filter/result_1.txt /tmp/result_1.txt" + try: + res = subprocess.check_output(cmd, shell=True) + except subprocess.CalledProcessError as e: + assert False, "Wrong output. return code: %d, Diff: %s" % (e.returncode, e.output) From b72fed7ed019c03689c27db1835ad43c0a2fc978 Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Thu, 2 Jul 2020 07:35:45 -0700 Subject: [PATCH 11/23] Tests of FRR templates which rendered by sonic-cfggen (#4875) * Tests of FRR templates which rendered by sonic-cfggen --- .../docker-fpm-frr/frr/bgpd/bgpd.main.conf.j2 | 1 + .../data/sonic-cfggen/bgpd.conf.j2/all.conf | 76 ++++++++++ .../data/sonic-cfggen/bgpd.conf.j2/all.json | 33 +++++ .../sonic-cfggen/bgpd.main.conf.j2/all.conf | 56 ++++++++ .../sonic-cfggen/bgpd.main.conf.j2/all.json | 32 +++++ .../sonic-cfggen/bgpd.main.conf.j2/base.conf | 22 +++ .../sonic-cfggen/bgpd.main.conf.j2/base.json | 19 +++ .../bgpd.main.conf.j2/defaults.conf | 56 ++++++++ .../bgpd.main.conf.j2/defaults.json | 29 ++++ .../base.conf | 39 +++++ .../base.json | 42 ++++++ .../sonic-cfggen/common/daemons.common.conf | 10 ++ .../common/daemons.common.conf.json | 7 + .../data/sonic-cfggen/common/functions.conf | 1 + .../sonic-cfggen/common/functions.conf.json | 1 + .../data/sonic-cfggen/frr.conf.j2/all.conf | 91 ++++++++++++ .../data/sonic-cfggen/frr.conf.j2/all.json | 46 ++++++ .../tests/data/sonic-cfggen/isolate/isolate | 17 +++ .../data/sonic-cfggen/isolate/isolate.json | 11 ++ .../tests/data/sonic-cfggen/isolate/unisolate | 17 +++ .../data/sonic-cfggen/isolate/unisolate.json | 11 ++ .../data/sonic-cfggen/staticd/staticd.conf | 19 +++ .../sonic-cfggen/staticd/staticd.conf.json | 12 ++ .../staticd/staticd.default_route.conf | 4 + .../staticd/staticd.default_route.conf.json | 7 + .../tests/data/sonic-cfggen/tsa/isolate.conf | 5 + .../tests/data/sonic-cfggen/tsa/isolate.json | 9 ++ .../data/sonic-cfggen/tsa/unisolate.conf | 3 + .../data/sonic-cfggen/tsa/unisolate.json | 3 + .../data/sonic-cfggen/zebra/interfaces.conf | 14 ++ .../data/sonic-cfggen/zebra/interfaces.json | 10 ++ .../data/sonic-cfggen/zebra/set_src.conf | 8 ++ .../data/sonic-cfggen/zebra/set_src.json | 5 + .../tests/data/sonic-cfggen/zebra/zebra.conf | 36 +++++ .../data/sonic-cfggen/zebra/zebra.conf.json | 23 +++ src/sonic-bgpcfgd/tests/test_sonic-cfggen.py | 133 ++++++++++++++++++ src/sonic-config-engine/sonic-cfggen | 2 + 37 files changed, 910 insertions(+) create mode 100644 src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.conf.j2/all.conf create mode 100644 src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.conf.j2/all.json create mode 100644 src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/all.conf create mode 100644 src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/all.json create mode 100644 src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/base.conf create mode 100644 src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/base.json create mode 100644 src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/defaults.conf create mode 100644 src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/defaults.json create mode 100644 src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.spine_chassis_frontend_router.conf.j2/base.conf create mode 100644 src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.spine_chassis_frontend_router.conf.j2/base.json create mode 100644 src/sonic-bgpcfgd/tests/data/sonic-cfggen/common/daemons.common.conf create mode 100644 src/sonic-bgpcfgd/tests/data/sonic-cfggen/common/daemons.common.conf.json create mode 100644 src/sonic-bgpcfgd/tests/data/sonic-cfggen/common/functions.conf create mode 100644 src/sonic-bgpcfgd/tests/data/sonic-cfggen/common/functions.conf.json create mode 100644 src/sonic-bgpcfgd/tests/data/sonic-cfggen/frr.conf.j2/all.conf create mode 100644 src/sonic-bgpcfgd/tests/data/sonic-cfggen/frr.conf.j2/all.json create mode 100644 src/sonic-bgpcfgd/tests/data/sonic-cfggen/isolate/isolate create mode 100644 src/sonic-bgpcfgd/tests/data/sonic-cfggen/isolate/isolate.json create mode 100644 src/sonic-bgpcfgd/tests/data/sonic-cfggen/isolate/unisolate create mode 100644 src/sonic-bgpcfgd/tests/data/sonic-cfggen/isolate/unisolate.json create mode 100644 src/sonic-bgpcfgd/tests/data/sonic-cfggen/staticd/staticd.conf create mode 100644 src/sonic-bgpcfgd/tests/data/sonic-cfggen/staticd/staticd.conf.json create mode 100644 src/sonic-bgpcfgd/tests/data/sonic-cfggen/staticd/staticd.default_route.conf create mode 100644 src/sonic-bgpcfgd/tests/data/sonic-cfggen/staticd/staticd.default_route.conf.json create mode 100644 src/sonic-bgpcfgd/tests/data/sonic-cfggen/tsa/isolate.conf create mode 100644 src/sonic-bgpcfgd/tests/data/sonic-cfggen/tsa/isolate.json create mode 100644 src/sonic-bgpcfgd/tests/data/sonic-cfggen/tsa/unisolate.conf create mode 100644 src/sonic-bgpcfgd/tests/data/sonic-cfggen/tsa/unisolate.json create mode 100644 src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/interfaces.conf create mode 100644 src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/interfaces.json create mode 100644 src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/set_src.conf create mode 100644 src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/set_src.json create mode 100644 src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/zebra.conf create mode 100644 src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/zebra.conf.json create mode 100644 src/sonic-bgpcfgd/tests/test_sonic-cfggen.py diff --git a/dockers/docker-fpm-frr/frr/bgpd/bgpd.main.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/bgpd.main.conf.j2 index 051cfa4e9d..ef98dcf9f1 100644 --- a/dockers/docker-fpm-frr/frr/bgpd/bgpd.main.conf.j2 +++ b/dockers/docker-fpm-frr/frr/bgpd/bgpd.main.conf.j2 @@ -1,3 +1,4 @@ +{% from "common/functions.conf.j2" import get_ipv4_loopback_address, get_ipv6_loopback_address %} ! ! template: bgpd/bgpd.main.conf.j2 ! diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.conf.j2/all.conf b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.conf.j2/all.conf new file mode 100644 index 0000000000..166a5c6475 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.conf.j2/all.conf @@ -0,0 +1,76 @@ +! +! template: bgpd/bgpd.conf.j2 +! +! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== +! generated by templates/quagga/bgpd.conf.j2 with config DB data +! file: bgpd.conf +! +! template: common/daemons.common.conf.j2 +! +hostname new_hostname +password zebra +enable password zebra +! +log syslog informational +log facility local4 +! +! end of template: common/daemons.common.conf.j2! +agentx +! +! template: bgpd/bgpd.main.conf.j2 +! +! bgp multiple-instance +! +! BGP configuration +! +! TSA configuration +! +ip prefix-list PL_LoopbackV4 permit 55.55.55.55/32 +! +ipv6 prefix-list PL_LoopbackV6 permit fc00::/64 +! +route-map HIDE_INTERNAL permit 10 + set community local-AS +! +router bgp 55555 +! + bgp log-neighbor-changes + no bgp default ipv4-unicast +! + bgp bestpath as-path multipath-relax +! + bgp graceful-restart restart-time 480 + bgp graceful-restart + bgp graceful-restart preserve-fw-state +! + bgp router-id 55.55.55.55 +! + network 55.55.55.55/32 +! + address-family ipv6 + network fc00::1/64 + exit-address-family +! + network 10.10.10.1/24 + address-family ipv6 + network fc01::1/64 + exit-address-family +! + address-family ipv4 + redistribute connected route-map HIDE_INTERNAL + exit-address-family + address-family ipv6 + redistribute connected route-map HIDE_INTERNAL + exit-address-family +! + address-family ipv4 + maximum-paths 32 + exit-address-family + address-family ipv6 + maximum-paths 32 + exit-address-family +! +! end of template: bgpd/bgpd.main.conf.j2 +!! +! end of template: bgpd/bgpd.conf.j2 +! diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.conf.j2/all.json b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.conf.j2/all.json new file mode 100644 index 0000000000..17e32589d8 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.conf.j2/all.json @@ -0,0 +1,33 @@ +{ + "DEVICE_METADATA": { + "localhost": { + "hostname": "new_hostname", + "bgp_asn": "55555", + "sub_role": "FrontEnd" + } + }, + "LOOPBACK_INTERFACE": { + "Loopback0|55.55.55.55/32": {}, + "Loopback0|fc00::1/128": {} + }, + "VLAN_INTERFACE": { + "Vlan10|10.10.10.1/24": {}, + "Vlan10|fc01::1/64": {} + }, + "constants": { + "bgp": { + "multipath_relax": { + "enabled": true + }, + "graceful_restart": { + "enabled": true, + "restart_time": 480 + }, + "maximum_paths": { + "enabled": true, + "ipv4": 32, + "ipv6": 32 + } + } + } +} diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/all.conf b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/all.conf new file mode 100644 index 0000000000..8edbdb60a6 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/all.conf @@ -0,0 +1,56 @@ +! +! template: bgpd/bgpd.main.conf.j2 +! +! bgp multiple-instance +! +! BGP configuration +! +! TSA configuration +! +ip prefix-list PL_LoopbackV4 permit 55.55.55.55/32 +! +ipv6 prefix-list PL_LoopbackV6 permit fc00::/64 +! +route-map HIDE_INTERNAL permit 10 + set community local-AS +! +router bgp 55555 +! + bgp log-neighbor-changes + no bgp default ipv4-unicast +! + bgp bestpath as-path multipath-relax +! + bgp graceful-restart restart-time 480 + bgp graceful-restart + bgp graceful-restart preserve-fw-state +! + bgp router-id 55.55.55.55 +! + network 55.55.55.55/32 +! + address-family ipv6 + network fc00::1/64 + exit-address-family +! + network 10.10.10.1/24 + address-family ipv6 + network fc01::1/64 + exit-address-family +! + address-family ipv4 + redistribute connected route-map HIDE_INTERNAL + exit-address-family + address-family ipv6 + redistribute connected route-map HIDE_INTERNAL + exit-address-family +! + address-family ipv4 + maximum-paths 32 + exit-address-family + address-family ipv6 + maximum-paths 32 + exit-address-family +! +! end of template: bgpd/bgpd.main.conf.j2 +! diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/all.json b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/all.json new file mode 100644 index 0000000000..36099674ac --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/all.json @@ -0,0 +1,32 @@ +{ + "DEVICE_METADATA": { + "localhost": { + "bgp_asn": "55555", + "sub_role": "FrontEnd" + } + }, + "LOOPBACK_INTERFACE": { + "Loopback0|55.55.55.55/32": {}, + "Loopback0|fc00::1/128": {} + }, + "VLAN_INTERFACE": { + "Vlan10|10.10.10.1/24": {}, + "Vlan10|fc01::1/64": {} + }, + "constants": { + "bgp": { + "multipath_relax": { + "enabled": true + }, + "graceful_restart": { + "enabled": true, + "restart_time": 480 + }, + "maximum_paths": { + "enabled": true, + "ipv4": 32, + "ipv6": 32 + } + } + } +} diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/base.conf b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/base.conf new file mode 100644 index 0000000000..97159456b6 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/base.conf @@ -0,0 +1,22 @@ +! +! template: bgpd/bgpd.main.conf.j2 +! +! bgp multiple-instance +! +! BGP configuration +! +! TSA configuration +! +ip prefix-list PL_LoopbackV4 permit 55.55.55.55/32 +! +router bgp 55555 +! + bgp log-neighbor-changes + no bgp default ipv4-unicast +! + bgp router-id 55.55.55.55 +! + network 55.55.55.55/32 +! +! end of template: bgpd/bgpd.main.conf.j2 +! diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/base.json b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/base.json new file mode 100644 index 0000000000..692d4c78f0 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/base.json @@ -0,0 +1,19 @@ +{ + "DEVICE_METADATA": { + "localhost": { + "bgp_asn": "55555", + "sub_role": "" + } + }, + "LOOPBACK_INTERFACE": { + "Loopback0|55.55.55.55/32": {}, + "Loopback1|fc00::1/128": {} + }, + "constants": { + "bgp": { + "multipath_relax": {}, + "graceful_restart": {}, + "maximum_paths": {} + } + } +} diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/defaults.conf b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/defaults.conf new file mode 100644 index 0000000000..b444fcd7e5 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/defaults.conf @@ -0,0 +1,56 @@ +! +! template: bgpd/bgpd.main.conf.j2 +! +! bgp multiple-instance +! +! BGP configuration +! +! TSA configuration +! +ip prefix-list PL_LoopbackV4 permit 55.55.55.55/32 +! +ipv6 prefix-list PL_LoopbackV6 permit fc00::/64 +! +route-map HIDE_INTERNAL permit 10 + set community local-AS +! +router bgp 55555 +! + bgp log-neighbor-changes + no bgp default ipv4-unicast +! + bgp bestpath as-path multipath-relax +! + bgp graceful-restart restart-time 240 + bgp graceful-restart + bgp graceful-restart preserve-fw-state +! + bgp router-id 55.55.55.55 +! + network 55.55.55.55/32 +! + address-family ipv6 + network fc00::1/64 + exit-address-family +! + network 10.10.10.1/24 + address-family ipv6 + network fc01::1/64 + exit-address-family +! + address-family ipv4 + redistribute connected route-map HIDE_INTERNAL + exit-address-family + address-family ipv6 + redistribute connected route-map HIDE_INTERNAL + exit-address-family +! + address-family ipv4 + maximum-paths 64 + exit-address-family + address-family ipv6 + maximum-paths 64 + exit-address-family +! +! end of template: bgpd/bgpd.main.conf.j2 +! diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/defaults.json b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/defaults.json new file mode 100644 index 0000000000..2db9bd771c --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/defaults.json @@ -0,0 +1,29 @@ +{ + "DEVICE_METADATA": { + "localhost": { + "bgp_asn": "55555", + "sub_role": "FrontEnd" + } + }, + "LOOPBACK_INTERFACE": { + "Loopback0|55.55.55.55/32": {}, + "Loopback0|fc00::1/128": {} + }, + "VLAN_INTERFACE": { + "Vlan10|10.10.10.1/24": {}, + "Vlan10|fc01::1/64": {} + }, + "constants": { + "bgp": { + "multipath_relax": { + "enabled": true + }, + "graceful_restart": { + "enabled": true + }, + "maximum_paths": { + "enabled": true + } + } + } +} diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.spine_chassis_frontend_router.conf.j2/base.conf b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.spine_chassis_frontend_router.conf.j2/base.conf new file mode 100644 index 0000000000..581eb107ec --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.spine_chassis_frontend_router.conf.j2/base.conf @@ -0,0 +1,39 @@ +! +! Vnet BGP instance +router bgp 555 vrf First + no bgp default ipv4-unicast + bgp log-neighbor-changes + bgp bestpath as-path multipath-relax + no bgp default ipv4-unicast + bgp graceful-restart restart-time 240 + bgp graceful-restart + bgp router-id 10.20.30.40 + neighbor 10.10.10.1 remote-as 10 + neighbor 10.10.10.1 description session1 + address-family ipv4 unicast + neighbor 10.10.10.1 activate + neighbor 10.10.10.1 soft-reconfiguration inbound + maximum-paths 64 + exit-address-family + address-family l2vpn evpn + advertise ipv4 unicast + exit-address-family +router bgp 555 vrf Second + no bgp default ipv4-unicast + bgp log-neighbor-changes + bgp bestpath as-path multipath-relax + no bgp default ipv4-unicast + bgp graceful-restart restart-time 240 + bgp graceful-restart + bgp router-id 10.20.30.40 + neighbor 20.20.20.1 remote-as 20 + neighbor 20.20.20.1 description session2 + address-family ipv4 unicast + neighbor 20.20.20.1 activate + neighbor 20.20.20.1 soft-reconfiguration inbound + maximum-paths 64 + exit-address-family + address-family l2vpn evpn + advertise ipv4 unicast + exit-address-family +! diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.spine_chassis_frontend_router.conf.j2/base.json b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.spine_chassis_frontend_router.conf.j2/base.json new file mode 100644 index 0000000000..d6f09fb113 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.spine_chassis_frontend_router.conf.j2/base.json @@ -0,0 +1,42 @@ +{ + "DEVICE_METADATA": { + "localhost": { + "bgp_asn": "555" + } + }, + "LOOPBACK_INTERFACE": { + "Loopback0|10.20.30.40/32": {} + }, + "VNET": { + "First": { + "vni": 10 + }, + "Second": { + "vni": 20 + } + }, + "INTERFACE": { + "Ethernet0": { + "vnet_name": "First" + }, + "Ethernet0|10.10.10.10/24": {}, + "Ethernet8": { + "vnet_name": "Second" + }, + "Ethernet8|20.20.20.20/24": {}, + "Ethernet10": {}, + "Ethernet10|20.20.20.20/24": {} + }, + "BGP_NEIGHBOR": { + "10.10.10.1": { + "asn": "10", + "name": "session1", + "local_addr": "10.10.10.10" + }, + "20.20.20.1": { + "asn": "20", + "name": "session2", + "local_addr": "20.20.20.20" + } + } +} \ No newline at end of file diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/common/daemons.common.conf b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/common/daemons.common.conf new file mode 100644 index 0000000000..14d7b99d07 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/common/daemons.common.conf @@ -0,0 +1,10 @@ +! template: common/daemons.common.conf.j2 +! +hostname test_hostname +password zebra +enable password zebra +! +log syslog informational +log facility local4 +! +! end of template: common/daemons.common.conf.j2 diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/common/daemons.common.conf.json b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/common/daemons.common.conf.json new file mode 100644 index 0000000000..8ef3e43694 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/common/daemons.common.conf.json @@ -0,0 +1,7 @@ +{ + "DEVICE_METADATA": { + "localhost": { + "hostname": "test_hostname" + } + } +} diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/common/functions.conf b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/common/functions.conf new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/common/functions.conf @@ -0,0 +1 @@ + diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/common/functions.conf.json b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/common/functions.conf.json new file mode 100644 index 0000000000..9e26dfeeb6 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/common/functions.conf.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/frr.conf.j2/all.conf b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/frr.conf.j2/all.conf new file mode 100644 index 0000000000..4c5e81f4f9 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/frr.conf.j2/all.conf @@ -0,0 +1,91 @@ +! +! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== +! generated by templates/frr.conf.j2 with config DB data +! file: frr.conf +! +! template: common/daemons.common.conf.j2 +! +hostname test_hostname +password zebra +enable password zebra +! +log syslog informational +log facility local4 +! +! end of template: common/daemons.common.conf.j2! +agentx +! +! Enable link-detect (default disabled) +interface Ethernet0 +link-detect +! +interface Ethernet4 +link-detect +! +interface PortChannel10 +link-detect +! +interface PortChannel20 +link-detect +! +!! +! +! set static default route to mgmt gateway as a backup to learned default +ip route 0.0.0.0/0 10.10.10.1 200 +!! +! +! template: bgpd/bgpd.main.conf.j2 +! +! bgp multiple-instance +! +! BGP configuration +! +! TSA configuration +! +ip prefix-list PL_LoopbackV4 permit 55.55.55.55/32 +! +ipv6 prefix-list PL_LoopbackV6 permit fc00::/64 +! +route-map HIDE_INTERNAL permit 10 + set community local-AS +! +router bgp 55555 +! + bgp log-neighbor-changes + no bgp default ipv4-unicast +! + bgp bestpath as-path multipath-relax +! + bgp graceful-restart restart-time 480 + bgp graceful-restart + bgp graceful-restart preserve-fw-state +! + bgp router-id 55.55.55.55 +! + network 55.55.55.55/32 +! + address-family ipv6 + network fc00::1/64 + exit-address-family +! + network 10.10.10.1/24 + address-family ipv6 + network fc01::1/64 + exit-address-family +! + address-family ipv4 + redistribute connected route-map HIDE_INTERNAL + exit-address-family + address-family ipv6 + redistribute connected route-map HIDE_INTERNAL + exit-address-family +! + address-family ipv4 + maximum-paths 32 + exit-address-family + address-family ipv6 + maximum-paths 32 + exit-address-family +! +! end of template: bgpd/bgpd.main.conf.j2 +!! diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/frr.conf.j2/all.json b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/frr.conf.j2/all.json new file mode 100644 index 0000000000..d81eba2b0f --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/frr.conf.j2/all.json @@ -0,0 +1,46 @@ +{ + "DEVICE_METADATA": { + "localhost": { + "bgp_asn": "55555", + "hostname": "test_hostname", + "sub_role": "FrontEnd" + } + }, + "INTERFACE": { + "Ethernet0|10.20.30.40/24": {}, + "Ethernet4|20.20.30.40/24": {} + }, + "PORTCHANNEL": { + "PortChannel10": {}, + "PortChannel20": {} + }, + "MGMT_INTERFACE": { + "eth0|10.10.10.10/24": { + "gwaddr": "10.10.10.1" + } + }, + "LOOPBACK_INTERFACE": { + "Loopback0|55.55.55.55/32": {}, + "Loopback0|fc00::1/128": {} + }, + "VLAN_INTERFACE": { + "Vlan10|10.10.10.1/24": {}, + "Vlan10|fc01::1/64": {} + }, + "constants": { + "bgp": { + "multipath_relax": { + "enabled": true + }, + "graceful_restart": { + "enabled": true, + "restart_time": 480 + }, + "maximum_paths": { + "enabled": true, + "ipv4": 32, + "ipv6": 32 + } + } + } +} \ No newline at end of file diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/isolate/isolate b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/isolate/isolate new file mode 100644 index 0000000000..74f1074952 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/isolate/isolate @@ -0,0 +1,17 @@ +#!/bin/bash +## vtysh only accepts script in stdin, so cannot be directly used in shebang +## Cut the tail of this script and feed vtysh stdin +sed -n -e '9,$p' < "$0" | vtysh "$@" +## Exit with vtysh return code +exit $? +## vtysh script start from next line, which line number MUST equal in 'sed' command above +configure terminal + router bgp 12345 + neighbor 10.20.30.40 route-map ISOLATE out + address-family ipv6 + neighbor fc00::1 route-map ISOLATE out + exit-address-family + exit +exit +clear ip bgp 10.20.30.40 soft out +clear ip bgp fc00::1 soft out diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/isolate/isolate.json b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/isolate/isolate.json new file mode 100644 index 0000000000..012b69ef30 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/isolate/isolate.json @@ -0,0 +1,11 @@ +{ + "DEVICE_METADATA": { + "localhost": { + "bgp_asn": "12345" + } + }, + "BGP_NEIGHBOR": { + "10.20.30.40": {}, + "fc00::1": {} + } +} diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/isolate/unisolate b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/isolate/unisolate new file mode 100644 index 0000000000..b9476d0b71 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/isolate/unisolate @@ -0,0 +1,17 @@ +#!/bin/bash +## vtysh only accepts script in stdin, so cannot be directly used in shebang +## Cut the tail of this script and feed vtysh stdin +sed -n -e '9,$p' < "$0" | vtysh "$@" +## Exit with vtysh return code +exit $? +## vtysh script start from next line, which line number MUST equal in 'sed' command above +configure terminal + router bgp 12345 + no neighbor 10.20.30.40 route-map ISOLATE out + address-family ipv6 + no neighbor fc00::1 route-map ISOLATE out + exit-address-family + exit +exit +clear ip bgp 10.20.30.40 soft out +clear ip bgp fc00::1 soft out diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/isolate/unisolate.json b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/isolate/unisolate.json new file mode 100644 index 0000000000..012b69ef30 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/isolate/unisolate.json @@ -0,0 +1,11 @@ +{ + "DEVICE_METADATA": { + "localhost": { + "bgp_asn": "12345" + } + }, + "BGP_NEIGHBOR": { + "10.20.30.40": {}, + "fc00::1": {} + } +} diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/staticd/staticd.conf b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/staticd/staticd.conf new file mode 100644 index 0000000000..522c0d36f2 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/staticd/staticd.conf @@ -0,0 +1,19 @@ +! +! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== +! generated by templates/frr/staticd.conf.j2 using config DB data +! file: staticd.conf +! +! template: common/daemons.common.conf.j2 +! +hostname new_hostname +password zebra +enable password zebra +! +log syslog informational +log facility local4 +! +! end of template: common/daemons.common.conf.j2! +! +! set static default route to mgmt gateway as a backup to learned default +ip route 0.0.0.0/0 10.10.10.1 200 +!! diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/staticd/staticd.conf.json b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/staticd/staticd.conf.json new file mode 100644 index 0000000000..37f660d101 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/staticd/staticd.conf.json @@ -0,0 +1,12 @@ +{ + "DEVICE_METADATA": { + "localhost": { + "hostname": "new_hostname" + } + }, + "MGMT_INTERFACE": { + "eth0|10.10.10.10/24": { + "gwaddr": "10.10.10.1" + } + } +} diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/staticd/staticd.default_route.conf b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/staticd/staticd.default_route.conf new file mode 100644 index 0000000000..11adb98ebc --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/staticd/staticd.default_route.conf @@ -0,0 +1,4 @@ +! +! set static default route to mgmt gateway as a backup to learned default +ip route 0.0.0.0/0 10.10.10.1 200 +! diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/staticd/staticd.default_route.conf.json b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/staticd/staticd.default_route.conf.json new file mode 100644 index 0000000000..80cd218a79 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/staticd/staticd.default_route.conf.json @@ -0,0 +1,7 @@ +{ + "MGMT_INTERFACE": { + "eth0|10.10.10.10/24": { + "gwaddr": "10.10.10.1" + } + } +} diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/tsa/isolate.conf b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/tsa/isolate.conf new file mode 100644 index 0000000000..7bd155fcdb --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/tsa/isolate.conf @@ -0,0 +1,5 @@ +route-map test_rm_name permit 2 + match ip address prefix-list PL_LoopbackV4 + set community 12345:555 +route-map test_rm_name deny 3 +! diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/tsa/isolate.json b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/tsa/isolate.json new file mode 100644 index 0000000000..708e4013f1 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/tsa/isolate.json @@ -0,0 +1,9 @@ +{ + "constants": { + "bgp": { + "traffic_shift_community": "12345:555" + } + }, + "route_map_name": "test_rm_name", + "ip_version": "V4" +} \ No newline at end of file diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/tsa/unisolate.conf b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/tsa/unisolate.conf new file mode 100644 index 0000000000..db53a69e7e --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/tsa/unisolate.conf @@ -0,0 +1,3 @@ +no route-map test_rm permit 2 +no route-map test_rm deny 3 +! diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/tsa/unisolate.json b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/tsa/unisolate.json new file mode 100644 index 0000000000..da07043149 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/tsa/unisolate.json @@ -0,0 +1,3 @@ +{ + "route_map_name": "test_rm" +} \ No newline at end of file diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/interfaces.conf b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/interfaces.conf new file mode 100644 index 0000000000..919c35085b --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/interfaces.conf @@ -0,0 +1,14 @@ +! +! Enable link-detect (default disabled) +interface Ethernet0 +link-detect +! +interface Ethernet4 +link-detect +! +interface PortChannel10 +link-detect +! +interface PortChannel20 +link-detect +! diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/interfaces.json b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/interfaces.json new file mode 100644 index 0000000000..e9c1bcba41 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/interfaces.json @@ -0,0 +1,10 @@ +{ + "INTERFACE": { + "Ethernet0|10.20.30.40/24": {}, + "Ethernet4|20.20.30.40/24": {} + }, + "PORTCHANNEL": { + "PortChannel10": {}, + "PortChannel20": {} + } +} \ No newline at end of file diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/set_src.conf b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/set_src.conf new file mode 100644 index 0000000000..b543d24e00 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/set_src.conf @@ -0,0 +1,8 @@ +! +! Set ip source to loopback for bgp learned routes +! +route-map new_rm_name permit 10 + set src 10.20.30.40 +! +ipv4 protocol bgp route-map new_rm_name +! diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/set_src.json b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/set_src.json new file mode 100644 index 0000000000..2e76d46fd1 --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/set_src.json @@ -0,0 +1,5 @@ +{ + "rm_name": "new_rm_name", + "lo_ip": "10.20.30.40", + "ip_proto": "v4" +} \ No newline at end of file diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/zebra.conf b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/zebra.conf new file mode 100644 index 0000000000..f7b30f214d --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/zebra.conf @@ -0,0 +1,36 @@ +! +! =========== Managed by sonic-cfggen DO NOT edit manually! ==================== +! generated by templates/zebra/zebra.conf.j2 using config DB data +! file: zebra.conf +! +! template: common/daemons.common.conf.j2 +! +hostname new_hostname +password zebra +enable password zebra +! +log syslog informational +log facility local4 +! +! end of template: common/daemons.common.conf.j2! +! +vrf First +vni 10 +! +vrf Second +vni 20 +! +! Enable link-detect (default disabled) +interface Ethernet0 +link-detect +! +interface Ethernet4 +link-detect +! +interface PortChannel10 +link-detect +! +interface PortChannel20 +link-detect +! +!! diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/zebra.conf.json b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/zebra.conf.json new file mode 100644 index 0000000000..9b63ff526f --- /dev/null +++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/zebra/zebra.conf.json @@ -0,0 +1,23 @@ +{ + "DEVICE_METADATA": { + "localhost": { + "hostname": "new_hostname" + } + }, + "VNET": { + "First": { + "vni": 10 + }, + "Second": { + "vni": 20 + } + }, + "INTERFACE": { + "Ethernet0|10.20.30.40/24": {}, + "Ethernet4|20.20.30.40/24": {} + }, + "PORTCHANNEL": { + "PortChannel10": {}, + "PortChannel20": {} + } +} \ No newline at end of file diff --git a/src/sonic-bgpcfgd/tests/test_sonic-cfggen.py b/src/sonic-bgpcfgd/tests/test_sonic-cfggen.py new file mode 100644 index 0000000000..065ecb815c --- /dev/null +++ b/src/sonic-bgpcfgd/tests/test_sonic-cfggen.py @@ -0,0 +1,133 @@ +import os +import subprocess + + +from app.config import ConfigMgr +from .test_templates import compress_comments, write_result + + +TEMPLATE_PATH = os.path.abspath('../../dockers/docker-fpm-frr/frr') +DATA_PATH = "tests/data/sonic-cfggen/" +CONSTANTS_PATH = os.path.abspath('../../files/image_config/constants/constants.yml') + + +def run_test(name, template_path, json_path, match_path): + template_path = os.path.join(TEMPLATE_PATH, template_path) + json_path = os.path.join(DATA_PATH, json_path) + cfggen = os.path.abspath("../sonic-config-engine/sonic-cfggen") + command = [cfggen, "-T", TEMPLATE_PATH, "-t", template_path, "-y", json_path] + p = subprocess.Popen(command, shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + stdout, stderr = p.communicate() + assert p.returncode == 0, "sonic-cfggen for %s test returned %d code. stderr='%s'" % (name, p.returncode, stderr) + raw_generated_result = stdout + assert "None" not in raw_generated_result, "Test %s" % name + canonical_generated_result = ConfigMgr.to_canonical(raw_generated_result) + match_path = os.path.join(DATA_PATH, match_path) + # only for development write_result(match_path, raw_generated_result) + with open(match_path) as result_fp: + raw_saved_result = result_fp.read() + canonical_saved_result = ConfigMgr.to_canonical(raw_saved_result) + assert canonical_saved_result == canonical_generated_result, "Test %s" % name + + +def test_bgpd_main_conf_base(): + run_test("Base bgpd.main.conf.j2", + "bgpd/bgpd.main.conf.j2", + "bgpd.main.conf.j2/base.json", + "bgpd.main.conf.j2/base.conf") + +def test_bgpd_main_conf_comprehensive(): + run_test("Comprehensive bgpd.main.conf.j2", + "bgpd/bgpd.main.conf.j2", + "bgpd.main.conf.j2/all.json", + "bgpd.main.conf.j2/all.conf") + +def test_bgpd_main_conf_defaults(): + run_test("Defaults bgpd.main.conf.j2", + "bgpd/bgpd.main.conf.j2", + "bgpd.main.conf.j2/defaults.json", + "bgpd.main.conf.j2/defaults.conf") + +def test_tsa_isolate(): + run_test("tsa/bgpd.tsa.isolate.conf.j2", + "bgpd/tsa/bgpd.tsa.isolate.conf.j2", + "tsa/isolate.json", + "tsa/isolate.conf") + +def test_tsa_unisolate(): + run_test("tsa/bgpd.tsa.unisolate.conf.j2", + "bgpd/tsa/bgpd.tsa.unisolate.conf.j2", + "tsa/unisolate.json", + "tsa/unisolate.conf") + +def test_common_daemons(): + run_test("daemons.common.conf.j2", + "common/daemons.common.conf.j2", + "common/daemons.common.conf.json", + "common/daemons.common.conf") + +def test_common_functions(): + run_test("functions.conf.j2", + "common/functions.conf.j2", + "common/functions.conf.json", + "common/functions.conf") + +def test_staticd_default_route(): + run_test("staticd.default_route.conf.j2", + "staticd/staticd.default_route.conf.j2", + "staticd/staticd.default_route.conf.json", + "staticd/staticd.default_route.conf") + +def test_staticd(): + run_test("staticd.conf.j2", + "staticd/staticd.conf.j2", + "staticd/staticd.conf.json", + "staticd/staticd.conf") + +def test_zebra_interfaces(): + run_test("zebra.interfaces.conf.j2", + "zebra/zebra.interfaces.conf.j2", + "zebra/interfaces.json", + "zebra/interfaces.conf") + +def test_zebra_set_src(): + run_test("zebra.set_src.conf.j2", + "zebra/zebra.set_src.conf.j2", + "zebra/set_src.json", + "zebra/set_src.conf") + +def test_zebra(): + run_test("zebra.conf.j2", + "zebra/zebra.conf.j2", + "zebra/zebra.conf.json", + "zebra/zebra.conf") + +def test_isolate(): + run_test("isolate.j2", + "isolate.j2", + "isolate/isolate.json", + "isolate/isolate") + +def test_unisolate(): + run_test("unisolate.j2", + "unisolate.j2", + "isolate/unisolate.json", + "isolate/unisolate") + +def test_frr_conf(): + run_test("frr.conf.j2", + "frr.conf.j2", + "frr.conf.j2/all.json", + "frr.conf.j2/all.conf") + +def test_l3vpn_base(): + run_test("bgpd spine_chassis_frontend_router.conf.j2", + "bgpd/bgpd.spine_chassis_frontend_router.conf.j2", + "bgpd.spine_chassis_frontend_router.conf.j2/base.json", + "bgpd.spine_chassis_frontend_router.conf.j2/base.conf") + +def test_bgp_conf_all(): + run_test("bgpd/bgpd.conf", + "bgpd/bgpd.conf.j2", + "bgpd.conf.j2/all.json", + "bgpd.conf.j2/all.conf") diff --git a/src/sonic-config-engine/sonic-cfggen b/src/sonic-config-engine/sonic-cfggen index 8528f828c8..1118703458 100755 --- a/src/sonic-config-engine/sonic-cfggen +++ b/src/sonic-config-engine/sonic-cfggen @@ -16,6 +16,8 @@ See usage string for detail description for arguments. """ from __future__ import print_function +import sys +sys.path.insert(0, "/usr/local/lib/python2.7/dist-packages") # monkey patch re.compile to do lazy regular expression compilation. # This is done to improve import time of jinja2, yaml, natsort modules, because they From cae65a451c6408cf932f8c8316c6747937c7f562 Mon Sep 17 00:00:00 2001 From: arlakshm <55814491+arlakshm@users.noreply.github.com> Date: Thu, 2 Jul 2020 11:37:40 -0700 Subject: [PATCH 12/23] [config]: Loopback Interface changes for multi ASIC devices (#4825) * Loopback IP changes for multi ASIC devices multi ASIC will have 2 Loopback Interfaces - Loopback0 has globally unique IP address, which is advertised by the multi ASIC device to its peers. This way all the external devices will see this device as a single device. - Loopback4096 is assigned an IP address which has a scope is within the device. Each ASIC has a different ip address for Loopback4096. This ip address will be used as Router-Id by the bgp instance on multi ASIC devices. This PR implements this change for multi ASIC devices Signed-off-by: Arvindsrinivasan Lakshmi Narasimhan --- .../docker-fpm-frr/frr/bgpd/bgpd.main.conf.j2 | 16 +++++++- src/sonic-config-engine/minigraph.py | 32 +++++++++++---- src/sonic-config-engine/sonic-cfggen | 3 ++ src/sonic-config-engine/sonic_device_util.py | 16 ++++++-- .../tests/multi_npu_data/sample-minigraph.xml | 40 +++++++++++++++++-- .../tests/test_multinpu_cfggen.py | 29 ++++++++++++++ 6 files changed, 120 insertions(+), 16 deletions(-) diff --git a/dockers/docker-fpm-frr/frr/bgpd/bgpd.main.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/bgpd.main.conf.j2 index ef98dcf9f1..0199b254d1 100644 --- a/dockers/docker-fpm-frr/frr/bgpd/bgpd.main.conf.j2 +++ b/dockers/docker-fpm-frr/frr/bgpd/bgpd.main.conf.j2 @@ -15,7 +15,7 @@ ipv6 prefix-list PL_LoopbackV6 permit {{ get_ipv6_loopback_address(LOOPBACK_INTE {% endif %} ! ! -{% if DEVICE_METADATA['localhost']['sub_role'] == 'FrontEnd' %} +{% if multi_asic() %} route-map HIDE_INTERNAL permit 10 set community local-AS ! @@ -38,16 +38,30 @@ router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} {% endif %} ! {# set router-id #} +{% if multi_asic() %} + bgp router-id {{ get_ipv4_loopback_address(LOOPBACK_INTERFACE, "Loopback4096") | ip }} +{% else %} bgp router-id {{ get_ipv4_loopback_address(LOOPBACK_INTERFACE, "Loopback0") | ip }} +{% endif %} ! {# advertise loopback #} network {{ get_ipv4_loopback_address(LOOPBACK_INTERFACE, "Loopback0") | ip }}/32 +{% if multi_asic() %} + network {{ get_ipv4_loopback_address(LOOPBACK_INTERFACE, "Loopback4096") | ip }}/32 route-map HIDE_INTERNAL +{% endif %} ! {% if get_ipv6_loopback_address(LOOPBACK_INTERFACE, "Loopback0") != 'None' %} address-family ipv6 network {{ get_ipv6_loopback_address(LOOPBACK_INTERFACE, "Loopback0") | ip }}/64 exit-address-family {% endif %} +{% if multi_asic() %} +{% if get_ipv6_loopback_address(LOOPBACK_INTERFACE, "Loopback4096") != 'None' %} + address-family ipv6 + network {{ get_ipv6_loopback_address(LOOPBACK_INTERFACE, "Loopback4096") | ip }}/64 route-map HIDE_INTERNAL + exit-address-family +{% endif %} +{% endif %} {% endblock bgp_init %} ! {% block vlan_advertisement %} diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index 79e553e019..2fe6999872 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -251,6 +251,15 @@ def parse_asic_png(png, asic_name, hostname): devices[name] = device_data return (neighbors, devices, port_speeds) +def parse_loopback_intf(child): + lointfs = child.find(str(QName(ns, "LoopbackIPInterfaces"))) + lo_intfs = {} + for lointf in lointfs.findall(str(QName(ns1, "LoopbackIPInterface"))): + intfname = lointf.find(str(QName(ns, "AttachTo"))).text + ipprefix = lointf.find(str(QName(ns1, "PrefixStr"))).text + lo_intfs[(intfname, ipprefix)] = {} + return lo_intfs + def parse_dpg(dpg, hname): aclintfs = None mgmtintfs = None @@ -269,7 +278,6 @@ def parse_dpg(dpg, hname): """ if mgmtintfs is None and child.find(str(QName(ns, "ManagementIPInterfaces"))) is not None: mgmtintfs = child.find(str(QName(ns, "ManagementIPInterfaces"))) - hostname = child.find(str(QName(ns, "Hostname"))) if hostname.text.lower() != hname.lower(): continue @@ -290,12 +298,7 @@ def parse_dpg(dpg, hname): ipprefix = ipintf.find(str(QName(ns, "Prefix"))).text intfs[(intfname, ipprefix)] = {} - lointfs = child.find(str(QName(ns, "LoopbackIPInterfaces"))) - lo_intfs = {} - for lointf in lointfs.findall(str(QName(ns1, "LoopbackIPInterface"))): - intfname = lointf.find(str(QName(ns, "AttachTo"))).text - ipprefix = lointf.find(str(QName(ns1, "PrefixStr"))).text - lo_intfs[(intfname, ipprefix)] = {} + lo_intfs = parse_loopback_intf(child) mvrfConfigs = child.find(str(QName(ns, "MgmtVrfConfigs"))) mvrf = {} @@ -452,6 +455,13 @@ def parse_dpg(dpg, hname): return intfs, lo_intfs, mvrf, mgmt_intf, vlans, vlan_members, pcs, pc_members, acls, vni return None, None, None, None, None, None, None, None, None, None +def parse_host_loopback(dpg, hname): + for child in dpg: + hostname = child.find(str(QName(ns, "Hostname"))) + if hostname.text.lower() != hname.lower(): + continue + lo_intfs = parse_loopback_intf(child) + return lo_intfs def parse_cpg(cpg, hname): bgp_sessions = {} @@ -826,6 +836,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw cloudtype = None hostname = None linkmetas = {} + host_lo_intfs = None # hostname is the asic_name, get the asic_id from the asic_name if asic_name is not None: @@ -867,6 +878,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw else: if child.tag == str(QName(ns, "DpgDec")): (intfs, lo_intfs, mvrf, mgmt_intf, vlans, vlan_members, pcs, pc_members, acls, vni) = parse_dpg(child, asic_name) + host_lo_intfs = parse_host_loopback(child, hostname) elif child.tag == str(QName(ns, "CpgDec")): (bgp_sessions, bgp_asn, bgp_peers_with_range, bgp_monitors) = parse_cpg(child, asic_name) enable_internal_bgp_session(bgp_sessions, filename, asic_name) @@ -930,6 +942,12 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw for lo_intf in lo_intfs: results['LOOPBACK_INTERFACE'][lo_intf] = lo_intfs[lo_intf] results['LOOPBACK_INTERFACE'][lo_intf[0]] = {} + + if host_lo_intfs is not None: + for host_lo_intf in host_lo_intfs: + results['LOOPBACK_INTERFACE'][host_lo_intf] = host_lo_intfs[host_lo_intf] + results['LOOPBACK_INTERFACE'][host_lo_intf[0]] = {} + results['MGMT_VRF_CONFIG'] = mvrf phyport_intfs = {} diff --git a/src/sonic-config-engine/sonic-cfggen b/src/sonic-config-engine/sonic-cfggen index 1118703458..9bda720719 100755 --- a/src/sonic-config-engine/sonic-cfggen +++ b/src/sonic-config-engine/sonic-cfggen @@ -45,6 +45,7 @@ from sonic_device_util import get_machine_info from sonic_device_util import get_platform_info from sonic_device_util import get_system_mac from sonic_device_util import get_npu_id_from_name +from sonic_device_util import is_multi_npu from config_samples import generate_sample_config from config_samples import get_available_config from swsssdk import SonicV2Connector, ConfigDBConnector, SonicDBConfig @@ -344,6 +345,8 @@ def main(): env.filters['ip_network'] = ip_network for attr in ['ip', 'network', 'prefixlen', 'netmask', 'broadcast']: env.filters[attr] = partial(prefix_attr, attr) + # Pass the is_multi_npu function as global + env.globals['multi_asic'] = is_multi_npu template = env.get_template(template_file) print(template.render(sort_data(data))) diff --git a/src/sonic-config-engine/sonic_device_util.py b/src/sonic-config-engine/sonic_device_util.py index 5984a7047f..ddfa751250 100644 --- a/src/sonic-config-engine/sonic_device_util.py +++ b/src/sonic-config-engine/sonic_device_util.py @@ -44,12 +44,20 @@ def get_npu_id_from_name(npu_name): else: return None +def get_asic_conf_file_path(platform): + asic_conf_path_candidates = [] + asic_conf_path_candidates.append(os.path.join('/usr/share/sonic/platform', ASIC_CONF_FILENAME)) + if platform is not None: + asic_conf_path_candidates.append(os.path.join(SONIC_DEVICE_PATH, platform, ASIC_CONF_FILENAME)) + for asic_conf_file_path in asic_conf_path_candidates: + if os.path.isfile(asic_conf_file_path): + return asic_conf_file_path + return None + def get_num_npus(): platform = get_platform_info(get_machine_info()) - if not platform: - return 1 - asic_conf_file_path = os.path.join(SONIC_DEVICE_PATH, platform, ASIC_CONF_FILENAME) - if not os.path.isfile(asic_conf_file_path): + asic_conf_file_path = get_asic_conf_file_path(platform) + if asic_conf_file_path is None: return 1 with open(asic_conf_file_path) as asic_conf_file: for line in asic_conf_file: diff --git a/src/sonic-config-engine/tests/multi_npu_data/sample-minigraph.xml b/src/sonic-config-engine/tests/multi_npu_data/sample-minigraph.xml index 8ca17925c6..412262315b 100644 --- a/src/sonic-config-engine/tests/multi_npu_data/sample-minigraph.xml +++ b/src/sonic-config-engine/tests/multi_npu_data/sample-minigraph.xml @@ -387,12 +387,20 @@ LoopbackInterface HostIP - Loopback0 + Loopback4096 8.0.0.0/32 8.0.0.0/32 + + HostIP1 + Loopback4096 + + FD00:1::32/128 + + FD00:1::32/128 + @@ -457,12 +465,20 @@ LoopbackInterface HostIP - Loopback0 + Loopback4096 8.0.0.1/32 8.0.0.1/32 + + HostIP1 + Loopback4096 + + FD00:2::32/128 + + FD00:2::32/128 + @@ -526,12 +542,20 @@ LoopbackInterface HostIP - Loopback0 + Loopback4096 8.0.0.4/32 8.0.0.4/32 + + HostIP1 + Loopback4096 + + FD00:3::32/128 + + FD00:3::32/128 + @@ -580,12 +604,20 @@ LoopbackInterface HostIP - Loopback0 + Loopback4096 8.0.0.5/32 8.0.0.5/32 + + HostIP1 + Loopback4096 + + FD00:4::32/128 + + FD00:4::32/128 + diff --git a/src/sonic-config-engine/tests/test_multinpu_cfggen.py b/src/sonic-config-engine/tests/test_multinpu_cfggen.py index c3307b482b..7511ce9bcd 100644 --- a/src/sonic-config-engine/tests/test_multinpu_cfggen.py +++ b/src/sonic-config-engine/tests/test_multinpu_cfggen.py @@ -245,3 +245,32 @@ def test_back_end_asic_acl(self): argument = "-m {} -p {} -n asic3 --var-json \"ACL_TABLE\"".format(self.sample_graph, self.port_config[3]) output = json.loads(self.run_script(argument)) self.assertDictEqual(output, {}) + + def test_loopback_intfs(self): + argument = "-m {} --var-json \"LOOPBACK_INTERFACE\"".format(self.sample_graph) + output = json.loads(self.run_script(argument)) + self.assertDictEqual(output, {\ + "Loopback0": {}, + "Loopback0|10.1.0.32/32": {}, + "Loopback0|FC00:1::32/128": {}}) + + # The asic configuration should have 2 loopback interfaces + argument = "-m {} -n asic0 --var-json \"LOOPBACK_INTERFACE\"".format(self.sample_graph) + output = json.loads(self.run_script(argument)) + self.assertDictEqual(output, { \ + "Loopback0": {}, + "Loopback4096": {}, + "Loopback0|10.1.0.32/32": {}, + "Loopback0|FC00:1::32/128": {}, + "Loopback4096|8.0.0.0/32": {}, + "Loopback4096|FD00:1::32/128": {}}) + + argument = "-m {} -n asic3 --var-json \"LOOPBACK_INTERFACE\"".format(self.sample_graph) + output = json.loads(self.run_script(argument)) + self.assertDictEqual(output, {\ + "Loopback0": {}, + "Loopback4096": {}, + "Loopback0|10.1.0.32/32": {}, + "Loopback0|FC00:1::32/128": {}, + "Loopback4096|8.0.0.5/32": {}, + "Loopback4096|FD00:4::32/128": {}}) From a4253afcda2f3ffa376f54a4aa9d81b8604236da Mon Sep 17 00:00:00 2001 From: Renuka Manavalan <47282725+renukamanavalan@users.noreply.github.com> Date: Thu, 2 Jul 2020 11:43:35 -0700 Subject: [PATCH 13/23] Added new pip packages, required by kube.py (kubernetes CLI). (#4884) --- platform/vs/docker-sonic-vs/Dockerfile.j2 | 3 +++ 1 file changed, 3 insertions(+) diff --git a/platform/vs/docker-sonic-vs/Dockerfile.j2 b/platform/vs/docker-sonic-vs/Dockerfile.j2 index 89abf3cd63..b58f782818 100644 --- a/platform/vs/docker-sonic-vs/Dockerfile.j2 +++ b/platform/vs/docker-sonic-vs/Dockerfile.j2 @@ -53,6 +53,9 @@ RUN pip install py2_ipaddress RUN pip install six RUN pip install pyroute2==0.5.3 netifaces==0.10.7 RUN pip install monotonic==1.5 +RUN pip install urllib3 +RUN pip install requests +RUN pip install crontab {% if docker_sonic_vs_debs.strip() -%} # Copy locally-built Debian package dependencies From 5f318426163f4769145d5127af7a66d7fd7a943f Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Fri, 3 Jul 2020 00:06:17 +0000 Subject: [PATCH 14/23] Revert "[config]: Loopback Interface changes for multi ASIC devices (#4825)" This reverts commit cae65a451c6408cf932f8c8316c6747937c7f562. --- .../docker-fpm-frr/frr/bgpd/bgpd.main.conf.j2 | 16 +------- src/sonic-config-engine/minigraph.py | 32 ++++----------- src/sonic-config-engine/sonic-cfggen | 3 -- src/sonic-config-engine/sonic_device_util.py | 16 ++------ .../tests/multi_npu_data/sample-minigraph.xml | 40 ++----------------- .../tests/test_multinpu_cfggen.py | 29 -------------- 6 files changed, 16 insertions(+), 120 deletions(-) diff --git a/dockers/docker-fpm-frr/frr/bgpd/bgpd.main.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/bgpd.main.conf.j2 index 0199b254d1..ef98dcf9f1 100644 --- a/dockers/docker-fpm-frr/frr/bgpd/bgpd.main.conf.j2 +++ b/dockers/docker-fpm-frr/frr/bgpd/bgpd.main.conf.j2 @@ -15,7 +15,7 @@ ipv6 prefix-list PL_LoopbackV6 permit {{ get_ipv6_loopback_address(LOOPBACK_INTE {% endif %} ! ! -{% if multi_asic() %} +{% if DEVICE_METADATA['localhost']['sub_role'] == 'FrontEnd' %} route-map HIDE_INTERNAL permit 10 set community local-AS ! @@ -38,30 +38,16 @@ router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} {% endif %} ! {# set router-id #} -{% if multi_asic() %} - bgp router-id {{ get_ipv4_loopback_address(LOOPBACK_INTERFACE, "Loopback4096") | ip }} -{% else %} bgp router-id {{ get_ipv4_loopback_address(LOOPBACK_INTERFACE, "Loopback0") | ip }} -{% endif %} ! {# advertise loopback #} network {{ get_ipv4_loopback_address(LOOPBACK_INTERFACE, "Loopback0") | ip }}/32 -{% if multi_asic() %} - network {{ get_ipv4_loopback_address(LOOPBACK_INTERFACE, "Loopback4096") | ip }}/32 route-map HIDE_INTERNAL -{% endif %} ! {% if get_ipv6_loopback_address(LOOPBACK_INTERFACE, "Loopback0") != 'None' %} address-family ipv6 network {{ get_ipv6_loopback_address(LOOPBACK_INTERFACE, "Loopback0") | ip }}/64 exit-address-family {% endif %} -{% if multi_asic() %} -{% if get_ipv6_loopback_address(LOOPBACK_INTERFACE, "Loopback4096") != 'None' %} - address-family ipv6 - network {{ get_ipv6_loopback_address(LOOPBACK_INTERFACE, "Loopback4096") | ip }}/64 route-map HIDE_INTERNAL - exit-address-family -{% endif %} -{% endif %} {% endblock bgp_init %} ! {% block vlan_advertisement %} diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index 2fe6999872..79e553e019 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -251,15 +251,6 @@ def parse_asic_png(png, asic_name, hostname): devices[name] = device_data return (neighbors, devices, port_speeds) -def parse_loopback_intf(child): - lointfs = child.find(str(QName(ns, "LoopbackIPInterfaces"))) - lo_intfs = {} - for lointf in lointfs.findall(str(QName(ns1, "LoopbackIPInterface"))): - intfname = lointf.find(str(QName(ns, "AttachTo"))).text - ipprefix = lointf.find(str(QName(ns1, "PrefixStr"))).text - lo_intfs[(intfname, ipprefix)] = {} - return lo_intfs - def parse_dpg(dpg, hname): aclintfs = None mgmtintfs = None @@ -278,6 +269,7 @@ def parse_dpg(dpg, hname): """ if mgmtintfs is None and child.find(str(QName(ns, "ManagementIPInterfaces"))) is not None: mgmtintfs = child.find(str(QName(ns, "ManagementIPInterfaces"))) + hostname = child.find(str(QName(ns, "Hostname"))) if hostname.text.lower() != hname.lower(): continue @@ -298,7 +290,12 @@ def parse_dpg(dpg, hname): ipprefix = ipintf.find(str(QName(ns, "Prefix"))).text intfs[(intfname, ipprefix)] = {} - lo_intfs = parse_loopback_intf(child) + lointfs = child.find(str(QName(ns, "LoopbackIPInterfaces"))) + lo_intfs = {} + for lointf in lointfs.findall(str(QName(ns1, "LoopbackIPInterface"))): + intfname = lointf.find(str(QName(ns, "AttachTo"))).text + ipprefix = lointf.find(str(QName(ns1, "PrefixStr"))).text + lo_intfs[(intfname, ipprefix)] = {} mvrfConfigs = child.find(str(QName(ns, "MgmtVrfConfigs"))) mvrf = {} @@ -455,13 +452,6 @@ def parse_dpg(dpg, hname): return intfs, lo_intfs, mvrf, mgmt_intf, vlans, vlan_members, pcs, pc_members, acls, vni return None, None, None, None, None, None, None, None, None, None -def parse_host_loopback(dpg, hname): - for child in dpg: - hostname = child.find(str(QName(ns, "Hostname"))) - if hostname.text.lower() != hname.lower(): - continue - lo_intfs = parse_loopback_intf(child) - return lo_intfs def parse_cpg(cpg, hname): bgp_sessions = {} @@ -836,7 +826,6 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw cloudtype = None hostname = None linkmetas = {} - host_lo_intfs = None # hostname is the asic_name, get the asic_id from the asic_name if asic_name is not None: @@ -878,7 +867,6 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw else: if child.tag == str(QName(ns, "DpgDec")): (intfs, lo_intfs, mvrf, mgmt_intf, vlans, vlan_members, pcs, pc_members, acls, vni) = parse_dpg(child, asic_name) - host_lo_intfs = parse_host_loopback(child, hostname) elif child.tag == str(QName(ns, "CpgDec")): (bgp_sessions, bgp_asn, bgp_peers_with_range, bgp_monitors) = parse_cpg(child, asic_name) enable_internal_bgp_session(bgp_sessions, filename, asic_name) @@ -942,12 +930,6 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw for lo_intf in lo_intfs: results['LOOPBACK_INTERFACE'][lo_intf] = lo_intfs[lo_intf] results['LOOPBACK_INTERFACE'][lo_intf[0]] = {} - - if host_lo_intfs is not None: - for host_lo_intf in host_lo_intfs: - results['LOOPBACK_INTERFACE'][host_lo_intf] = host_lo_intfs[host_lo_intf] - results['LOOPBACK_INTERFACE'][host_lo_intf[0]] = {} - results['MGMT_VRF_CONFIG'] = mvrf phyport_intfs = {} diff --git a/src/sonic-config-engine/sonic-cfggen b/src/sonic-config-engine/sonic-cfggen index 9bda720719..1118703458 100755 --- a/src/sonic-config-engine/sonic-cfggen +++ b/src/sonic-config-engine/sonic-cfggen @@ -45,7 +45,6 @@ from sonic_device_util import get_machine_info from sonic_device_util import get_platform_info from sonic_device_util import get_system_mac from sonic_device_util import get_npu_id_from_name -from sonic_device_util import is_multi_npu from config_samples import generate_sample_config from config_samples import get_available_config from swsssdk import SonicV2Connector, ConfigDBConnector, SonicDBConfig @@ -345,8 +344,6 @@ def main(): env.filters['ip_network'] = ip_network for attr in ['ip', 'network', 'prefixlen', 'netmask', 'broadcast']: env.filters[attr] = partial(prefix_attr, attr) - # Pass the is_multi_npu function as global - env.globals['multi_asic'] = is_multi_npu template = env.get_template(template_file) print(template.render(sort_data(data))) diff --git a/src/sonic-config-engine/sonic_device_util.py b/src/sonic-config-engine/sonic_device_util.py index ddfa751250..5984a7047f 100644 --- a/src/sonic-config-engine/sonic_device_util.py +++ b/src/sonic-config-engine/sonic_device_util.py @@ -44,20 +44,12 @@ def get_npu_id_from_name(npu_name): else: return None -def get_asic_conf_file_path(platform): - asic_conf_path_candidates = [] - asic_conf_path_candidates.append(os.path.join('/usr/share/sonic/platform', ASIC_CONF_FILENAME)) - if platform is not None: - asic_conf_path_candidates.append(os.path.join(SONIC_DEVICE_PATH, platform, ASIC_CONF_FILENAME)) - for asic_conf_file_path in asic_conf_path_candidates: - if os.path.isfile(asic_conf_file_path): - return asic_conf_file_path - return None - def get_num_npus(): platform = get_platform_info(get_machine_info()) - asic_conf_file_path = get_asic_conf_file_path(platform) - if asic_conf_file_path is None: + if not platform: + return 1 + asic_conf_file_path = os.path.join(SONIC_DEVICE_PATH, platform, ASIC_CONF_FILENAME) + if not os.path.isfile(asic_conf_file_path): return 1 with open(asic_conf_file_path) as asic_conf_file: for line in asic_conf_file: diff --git a/src/sonic-config-engine/tests/multi_npu_data/sample-minigraph.xml b/src/sonic-config-engine/tests/multi_npu_data/sample-minigraph.xml index 412262315b..8ca17925c6 100644 --- a/src/sonic-config-engine/tests/multi_npu_data/sample-minigraph.xml +++ b/src/sonic-config-engine/tests/multi_npu_data/sample-minigraph.xml @@ -387,20 +387,12 @@ LoopbackInterface HostIP - Loopback4096 + Loopback0 8.0.0.0/32 8.0.0.0/32 - - HostIP1 - Loopback4096 - - FD00:1::32/128 - - FD00:1::32/128 - @@ -465,20 +457,12 @@ LoopbackInterface HostIP - Loopback4096 + Loopback0 8.0.0.1/32 8.0.0.1/32 - - HostIP1 - Loopback4096 - - FD00:2::32/128 - - FD00:2::32/128 - @@ -542,20 +526,12 @@ LoopbackInterface HostIP - Loopback4096 + Loopback0 8.0.0.4/32 8.0.0.4/32 - - HostIP1 - Loopback4096 - - FD00:3::32/128 - - FD00:3::32/128 - @@ -604,20 +580,12 @@ LoopbackInterface HostIP - Loopback4096 + Loopback0 8.0.0.5/32 8.0.0.5/32 - - HostIP1 - Loopback4096 - - FD00:4::32/128 - - FD00:4::32/128 - diff --git a/src/sonic-config-engine/tests/test_multinpu_cfggen.py b/src/sonic-config-engine/tests/test_multinpu_cfggen.py index 7511ce9bcd..c3307b482b 100644 --- a/src/sonic-config-engine/tests/test_multinpu_cfggen.py +++ b/src/sonic-config-engine/tests/test_multinpu_cfggen.py @@ -245,32 +245,3 @@ def test_back_end_asic_acl(self): argument = "-m {} -p {} -n asic3 --var-json \"ACL_TABLE\"".format(self.sample_graph, self.port_config[3]) output = json.loads(self.run_script(argument)) self.assertDictEqual(output, {}) - - def test_loopback_intfs(self): - argument = "-m {} --var-json \"LOOPBACK_INTERFACE\"".format(self.sample_graph) - output = json.loads(self.run_script(argument)) - self.assertDictEqual(output, {\ - "Loopback0": {}, - "Loopback0|10.1.0.32/32": {}, - "Loopback0|FC00:1::32/128": {}}) - - # The asic configuration should have 2 loopback interfaces - argument = "-m {} -n asic0 --var-json \"LOOPBACK_INTERFACE\"".format(self.sample_graph) - output = json.loads(self.run_script(argument)) - self.assertDictEqual(output, { \ - "Loopback0": {}, - "Loopback4096": {}, - "Loopback0|10.1.0.32/32": {}, - "Loopback0|FC00:1::32/128": {}, - "Loopback4096|8.0.0.0/32": {}, - "Loopback4096|FD00:1::32/128": {}}) - - argument = "-m {} -n asic3 --var-json \"LOOPBACK_INTERFACE\"".format(self.sample_graph) - output = json.loads(self.run_script(argument)) - self.assertDictEqual(output, {\ - "Loopback0": {}, - "Loopback4096": {}, - "Loopback0|10.1.0.32/32": {}, - "Loopback0|FC00:1::32/128": {}, - "Loopback4096|8.0.0.5/32": {}, - "Loopback4096|FD00:4::32/128": {}}) From c4b5b002c32aceb4ee3af2cb1bea3809373e9aef Mon Sep 17 00:00:00 2001 From: lguohan Date: Thu, 2 Jul 2020 22:03:50 -0700 Subject: [PATCH 15/23] [docker-orchagent]: make build depends only on sairedis package (#4880) make swss build depends only on libsairedis instead of syncd. This allows to build swss without depending on vendor sai library. Currently, libsairedis build also buils syncd which requires vendor SAI lib. This makes difficult to build swss docker in buster while still keeping syncd docker in stretch, as swss requires libsairedis which also build syncd and requires vendor to provide SAI for buster. As swss docker does not really contain syncd binary, so it is not necessary to build syncd for swss docker. * [submodule]: update sonic-sairedis * ccbb3bc 2020-06-28 | add option to build without syncd (HEAD, origin/master, origin/HEAD) [Guohan Lu] * 4247481 2020-06-28 | install saidiscovery into syncd package [Guohan Lu] * 61b8e8e 2020-06-26 | Revert "sonic-sairedis: Add support to sonic-sairedis for gearbox phys (#624)" (#630) [Danny Allen] * 85e543c 2020-06-26 | add a README to tests directory to describe how to run 'make check' (#629) [Syd Logan] * 2772f15 2020-06-26 | sonic-sairedis: Add support to sonic-sairedis for gearbox phys (#624) [Syd Logan] Signed-off-by: Guohan Lu --- platform/barefoot/bfn-sai.mk | 1 + platform/barefoot/rules.mk | 8 ++++---- platform/broadcom/rules.mk | 6 +++--- platform/broadcom/sai.mk | 1 + platform/cavium/rules.mk | 6 +++--- platform/centec/rules.mk | 6 +++--- platform/centec/sdk.mk | 1 + platform/innovium/invm-sai.mk | 2 ++ platform/innovium/rules.mk | 4 ++-- platform/marvell-arm64/rules.mk | 6 +++--- platform/marvell-arm64/sai.mk | 1 + platform/marvell-armhf/rules.mk | 6 +++--- platform/marvell-armhf/sai.mk | 1 + platform/marvell/rules.mk | 6 +++--- platform/marvell/sai.mk | 2 ++ platform/mellanox/mlnx-sai.mk | 1 + platform/mellanox/rules.mk | 6 +++--- platform/nephos/rules.mk | 6 +++--- platform/nephos/sai.mk | 3 ++- platform/p4/rules.mk | 6 +++--- platform/vs/syncd-vs.mk | 3 --- rules/sairedis.mk | 35 +------------------------------- rules/swss.mk | 4 +++- rules/syncd.dep | 20 ++++++++++++++++++ rules/syncd.mk | 36 +++++++++++++++++++++++++++++++++ slave.mk | 23 ++++++++++++++++++++- src/sonic-sairedis | 2 +- 27 files changed, 128 insertions(+), 74 deletions(-) create mode 100644 rules/syncd.dep create mode 100644 rules/syncd.mk diff --git a/platform/barefoot/bfn-sai.mk b/platform/barefoot/bfn-sai.mk index 39b8f36918..3ba9516203 100644 --- a/platform/barefoot/bfn-sai.mk +++ b/platform/barefoot/bfn-sai.mk @@ -6,3 +6,4 @@ $(BFN_SAI)_RDEPENDS += $(LIBNL_GENL3) SONIC_ONLINE_DEBS += $(BFN_SAI) $(BFN_SAI_DEV)_DEPENDS += $(BFN_SAI) +$(BFN_SAI_DEV)_CONFLICTS += $(LIBSAIVS_DEV) diff --git a/platform/barefoot/rules.mk b/platform/barefoot/rules.mk index 2e45dce8e7..e223d02c05 100644 --- a/platform/barefoot/rules.mk +++ b/platform/barefoot/rules.mk @@ -19,12 +19,12 @@ include $(PLATFORM_PATH)/bfn-modules.mk SONIC_ALL += $(SONIC_ONE_IMAGE) $(SONIC_ONE_ABOOT) \ $(DOCKER_FPM) -# Inject sai into sairedis -#$(LIBSAIREDIS)_DEPENDS += $(BFN_SAI) $(WNC_OSW1800_PLATFORM) $(BFN_INGRASYS_PLATFORM) $(BFN_PLATFORM) -$(LIBSAIREDIS)_DEPENDS += $(BFN_SAI) $(BFN_INGRASYS_PLATFORM) $(BFN_PLATFORM) +# Inject sai into syncd +#$(SYNCD)_DEPENDS += $(BFN_SAI) $(WNC_OSW1800_PLATFORM) $(BFN_INGRASYS_PLATFORM) $(BFN_PLATFORM) +$(SYNCD)_DEPENDS += $(BFN_SAI) $(BFN_INGRASYS_PLATFORM) $(BFN_PLATFORM) ifeq ($(ENABLE_SYNCD_RPC),y) -$(LIBSAIREDIS)_DEPENDS += $(LIBSAITHRIFT_DEV) +$(SYNCD)_DEPENDS += $(LIBSAITHRIFT_DEV) endif # Runtime dependency on sai is set only for syncd diff --git a/platform/broadcom/rules.mk b/platform/broadcom/rules.mk index 8dd7b2c8cb..afcec34a73 100644 --- a/platform/broadcom/rules.mk +++ b/platform/broadcom/rules.mk @@ -32,10 +32,10 @@ SONIC_ONLINE_FILES += $(BCMCMD) $(DSSERVE) SONIC_ALL += $(SONIC_ONE_IMAGE) $(SONIC_ONE_ABOOT_IMAGE) \ $(DOCKER_FPM) -# Inject brcm sai into sairedis -$(LIBSAIREDIS)_DEPENDS += $(BRCM_SAI) $(BRCM_SAI_DEV) +# Inject brcm sai into syncd +$(SYNCD)_DEPENDS += $(BRCM_SAI) $(BRCM_SAI_DEV) ifeq ($(ENABLE_SYNCD_RPC),y) -$(LIBSAIREDIS)_DEPENDS += $(LIBSAITHRIFT_DEV) +$(SYNCD)_DEPENDS += $(LIBSAITHRIFT_DEV) endif # Runtime dependency on brcm sai is set only for syncd diff --git a/platform/broadcom/sai.mk b/platform/broadcom/sai.mk index bda1231bf2..95a97d7b1b 100644 --- a/platform/broadcom/sai.mk +++ b/platform/broadcom/sai.mk @@ -6,3 +6,4 @@ $(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsa SONIC_ONLINE_DEBS += $(BRCM_SAI) $(BRCM_SAI_DEV)_DEPENDS += $(BRCM_SAI) +$(BRCM_SAI_DEV)_CONFLICTS += $(LIBSAIVS_DEV) diff --git a/platform/cavium/rules.mk b/platform/cavium/rules.mk index 2da9f5cca9..acdd7477fd 100644 --- a/platform/cavium/rules.mk +++ b/platform/cavium/rules.mk @@ -12,10 +12,10 @@ SONIC_ALL += $(SONIC_ONE_IMAGE) \ $(DOCKER_PTF_CAVM) \ $(DOCKER_SYNCD_CAVM_RPC) -# Inject cavium sai into sairedis -$(LIBSAIREDIS)_DEPENDS += $(CAVM_SAI) $(CAVM_LIBSAI) +# Inject cavium sai into syncd +$(SYNCD)_DEPENDS += $(CAVM_SAI) $(CAVM_LIBSAI) ifeq ($(ENABLE_SYNCD_RPC),y) -$(LIBSAIREDIS)_DEPENDS += $(LIBSAITHRIFT_DEV_CAVM) +$(SYNCD)_DEPENDS += $(LIBSAITHRIFT_DEV_CAVM) endif # Runtime dependency on cavium sai is set only for syncd diff --git a/platform/centec/rules.mk b/platform/centec/rules.mk index 6f3ac98eca..0c9f5a0309 100644 --- a/platform/centec/rules.mk +++ b/platform/centec/rules.mk @@ -9,10 +9,10 @@ include $(PLATFORM_PATH)/docker-ptf-centec.mk SONIC_ALL += $(SONIC_ONE_IMAGE) -# Inject centec sai into sairedis -$(LIBSAIREDIS)_DEPENDS += $(CENTEC_SAI) +# Inject centec sai into syncd +$(SYNCD)_DEPENDS += $(CENTEC_SAI) ifeq ($(ENABLE_SYNCD_RPC),y) -$(LIBSAIREDIS)_DEPENDS += $(LIBSAITHRIFT_DEV) +$(SYNCD)_DEPENDS += $(LIBSAITHRIFT_DEV) endif # Runtime dependency on centec sai is set only for syncd diff --git a/platform/centec/sdk.mk b/platform/centec/sdk.mk index 5a5c888e0b..724c157356 100644 --- a/platform/centec/sdk.mk +++ b/platform/centec/sdk.mk @@ -1,5 +1,6 @@ # Centec SAI CENTEC_SAI = libsai_1.6.1_amd64.deb $(CENTEC_SAI)_URL = https://github.com/CentecNetworks/sonic-binaries/raw/master/amd64/libsai_1.6.1-1.0_amd64.deb +$(CENTEC_SAI)_CONFLICTS += $(LIBSAIVS_DEV) SONIC_ONLINE_DEBS += $(CENTEC_SAI) diff --git a/platform/innovium/invm-sai.mk b/platform/innovium/invm-sai.mk index 9f01320820..c375572b1d 100755 --- a/platform/innovium/invm-sai.mk +++ b/platform/innovium/invm-sai.mk @@ -10,4 +10,6 @@ $(INVM_LIBSAI)_URL = $(INVM_SAI_ONLINE)/$(INVM_LIBSAI) $(INVM_HSAI)_URL = $(INVM_SAI_ONLINE)/$(INVM_HSAI) $(INVM_DRV)_URL = $(INVM_SAI_ONLINE)/$(INVM_DRV) +$(INVM_HSAI)_CONFLICTS += $(LIBSAIVS_DEV) + SONIC_ONLINE_DEBS += $(INVM_LIBSAI) $(INVM_HSAI) $(INVM_DRV) diff --git a/platform/innovium/rules.mk b/platform/innovium/rules.mk index 68a9dbb410..69b29afb98 100755 --- a/platform/innovium/rules.mk +++ b/platform/innovium/rules.mk @@ -13,8 +13,8 @@ SONIC_ALL += $(SONIC_INVM_ONE_IMAGE) \ $(DOCKER_PTF_INVM) \ $(DOCKER_SYNCD_INVM_RPC) -# Inject invm sai into sairedis -$(LIBSAIREDIS)_DEPENDS += $(INVM_HSAI) $(INVM_LIBSAI) $(LIBSAITHRIFT_DEV_INVM) +# Inject invm sai into syncd +$(SYNCD)_DEPENDS += $(INVM_HSAI) $(INVM_LIBSAI) $(LIBSAITHRIFT_DEV_INVM) # Runtime dependency on invm sai is set only for syncd $(SYNCD)_RDEPENDS += $(INVM_HSAI) diff --git a/platform/marvell-arm64/rules.mk b/platform/marvell-arm64/rules.mk index bf4667a46d..5c63392de9 100644 --- a/platform/marvell-arm64/rules.mk +++ b/platform/marvell-arm64/rules.mk @@ -15,10 +15,10 @@ SONIC_ALL += $(SONIC_ONE_IMAGE) \ $(DOCKER_PTF_MRVL) \ $(DOCKER_SYNCD_MRVL_RPC) -# Inject mrvl sai into sairedis -$(LIBSAIREDIS)_DEPENDS += $(MRVL_SAI) +# Inject mrvl sai into syncd +$(SYNCD)_DEPENDS += $(MRVL_SAI) ifeq ($(ENABLE_SYNCD_RPC),y) -$(LIBSAIREDIS)_DEPENDS += $(LIBSAITHRIFT_DEV) +$(SYNCD)_DEPENDS += $(LIBSAITHRIFT_DEV) endif # Runtime dependency on mrvl sai is set only for syncd diff --git a/platform/marvell-arm64/sai.mk b/platform/marvell-arm64/sai.mk index ebdd7030a3..1de18debe6 100644 --- a/platform/marvell-arm64/sai.mk +++ b/platform/marvell-arm64/sai.mk @@ -4,4 +4,5 @@ export MRVL_SAI_VERSION = 1.5.1 export MRVL_SAI = mrvllibsai_$(PLATFORM_ARCH)_$(MRVL_SAI_VERSION).deb $(MRVL_SAI)_SRC_PATH = $(PLATFORM_PATH)/sai +$(MRVL_SAI)_CONFLICTS = $(LIBSAIVS_DEV) SONIC_MAKE_DEBS += $(MRVL_SAI) diff --git a/platform/marvell-armhf/rules.mk b/platform/marvell-armhf/rules.mk index 05ca478806..bb4c3f0d4f 100644 --- a/platform/marvell-armhf/rules.mk +++ b/platform/marvell-armhf/rules.mk @@ -16,10 +16,10 @@ SONIC_ALL += $(SONIC_ONE_IMAGE) \ $(DOCKER_FPM) #$(DOCKER_SYNCD_MRVL_RPC) -# Inject mrvl sai into sairedis -$(LIBSAIREDIS)_DEPENDS += $(MRVL_SAI) +# Inject mrvl sai into syncd +$(SYNCD)_DEPENDS += $(MRVL_SAI) ifeq ($(ENABLE_SYNCD_RPC),y) -$(LIBSAIREDIS)_DEPENDS += $(LIBSAITHRIFT_DEV) +$(SYNCD)_DEPENDS += $(LIBSAITHRIFT_DEV) endif # Runtime dependency on mrvl sai is set only for syncd diff --git a/platform/marvell-armhf/sai.mk b/platform/marvell-armhf/sai.mk index ebdd7030a3..1de18debe6 100644 --- a/platform/marvell-armhf/sai.mk +++ b/platform/marvell-armhf/sai.mk @@ -4,4 +4,5 @@ export MRVL_SAI_VERSION = 1.5.1 export MRVL_SAI = mrvllibsai_$(PLATFORM_ARCH)_$(MRVL_SAI_VERSION).deb $(MRVL_SAI)_SRC_PATH = $(PLATFORM_PATH)/sai +$(MRVL_SAI)_CONFLICTS = $(LIBSAIVS_DEV) SONIC_MAKE_DEBS += $(MRVL_SAI) diff --git a/platform/marvell/rules.mk b/platform/marvell/rules.mk index c01e1e4918..442af4cbe9 100644 --- a/platform/marvell/rules.mk +++ b/platform/marvell/rules.mk @@ -8,10 +8,10 @@ SONIC_ALL += $(SONIC_ONE_IMAGE) \ $(DOCKER_FPM) \ $(DOCKER_SYNCD_MRVL_RPC) -# Inject mrvl sai into sairedis -$(LIBSAIREDIS)_DEPENDS += $(MRVL_FPA) $(MRVL_SAI) +# Inject mrvl sai into syncd +$(SYNCD)_DEPENDS += $(MRVL_FPA) $(MRVL_SAI) ifeq ($(ENABLE_SYNCD_RPC),y) -$(LIBSAIREDIS)_DEPENDS += $(LIBSAITHRIFT_DEV) +$(SYNCD)_DEPENDS += $(LIBSAITHRIFT_DEV) endif # Runtime dependency on mrvl sai is set only for syncd diff --git a/platform/marvell/sai.mk b/platform/marvell/sai.mk index 5531881000..9e09627c98 100644 --- a/platform/marvell/sai.mk +++ b/platform/marvell/sai.mk @@ -4,4 +4,6 @@ export MRVL_SAI_VERSION = 1.5.1 export MRVL_SAI = mrvllibsai_amd64_$(MRVL_SAI_VERSION).deb $(MRVL_SAI)_SRC_PATH = $(PLATFORM_PATH)/sai +$(MRVL_SAI)_CONFLICTS = $(LIBSAIVS_DEV) + SONIC_MAKE_DEBS += $(MRVL_SAI) diff --git a/platform/mellanox/mlnx-sai.mk b/platform/mellanox/mlnx-sai.mk index a978926f33..9e9075a6eb 100644 --- a/platform/mellanox/mlnx-sai.mk +++ b/platform/mellanox/mlnx-sai.mk @@ -8,6 +8,7 @@ MLNX_SAI = mlnx-sai_1.mlnx.$(MLNX_SAI_VERSION)_amd64.deb $(MLNX_SAI)_SRC_PATH = $(PLATFORM_PATH)/mlnx-sai $(MLNX_SAI)_DEPENDS += $(MLNX_SDK_DEBS) $(MLNX_SAI)_RDEPENDS += $(MLNX_SDK_RDEBS) $(MLNX_SDK_DEBS) +$(MLNX_SAI)_CONFLICTS += $(LIBSAIVS_DEV) MLNX_SAI_DBGSYM = mlnx-sai-dbgsym_1.mlnx.$(MLNX_SAI_VERSION)_amd64.deb $(eval $(call add_derived_package,$(MLNX_SAI),$(MLNX_SAI_DBGSYM))) SONIC_MAKE_DEBS += $(MLNX_SAI) diff --git a/platform/mellanox/rules.mk b/platform/mellanox/rules.mk index 1270579e29..74a87bdb29 100644 --- a/platform/mellanox/rules.mk +++ b/platform/mellanox/rules.mk @@ -18,10 +18,10 @@ include $(PLATFORM_PATH)/mlnx-ssd-fw-update.mk SONIC_ALL += $(SONIC_ONE_IMAGE) \ $(DOCKER_FPM) -# Inject mlnx sai into sairedis -$(LIBSAIREDIS)_DEPENDS += $(MLNX_SAI) +# Inject mlnx sai into syncd +$(SYNCD)_DEPENDS += $(MLNX_SAI) ifeq ($(ENABLE_SYNCD_RPC),y) -$(LIBSAIREDIS)_DEPENDS += $(LIBSAITHRIFT_DEV) +$(SYNCD)_DEPENDS += $(LIBSAITHRIFT_DEV) endif # Runtime dependency on mlnx sai is set only for syncd diff --git a/platform/nephos/rules.mk b/platform/nephos/rules.mk index 5c115eeaf8..727f6ab461 100644 --- a/platform/nephos/rules.mk +++ b/platform/nephos/rules.mk @@ -22,10 +22,10 @@ SONIC_ONLINE_FILES += $(NPX_DIAG) $(WARM_VERIFIER) $(DSSERVE) SONIC_ALL += $(SONIC_ONE_IMAGE) $(DOCKER_FPM) -# Inject nephos sai into sairedis -$(LIBSAIREDIS)_DEPENDS += $(NEPHOS_SAI) $(NEPHOS_SAI_DEV) +# Inject nephos sai into syncd +$(SYNCD)_DEPENDS += $(NEPHOS_SAI) $(NEPHOS_SAI_DEV) ifeq ($(ENABLE_SYNCD_RPC),y) -$(LIBSAIREDIS)_DEPENDS += $(LIBSAITHRIFT_DEV) +$(SYNCD)_DEPENDS += $(LIBSAITHRIFT_DEV) endif # Runtime dependency on nephos sai is set only for syncd diff --git a/platform/nephos/sai.mk b/platform/nephos/sai.mk index 5f7c4a23ae..2f457e6ecb 100644 --- a/platform/nephos/sai.mk +++ b/platform/nephos/sai.mk @@ -3,7 +3,7 @@ SAI_VERSION = 1.5.0 SAI_COMMIT_ID = 06a67d # Place here URL where SAI deb exist -NEPHOS_SAI_DEB_LOCAL_URL = +NEPHOS_SAI_DEB_LOCAL_URL = export NEPHOS_SAI_DEB_LOCAL_URL # ifneq ($(NEPHOS_SAI_DEB_LOCAL_URL), ) @@ -33,3 +33,4 @@ else SONIC_ONLINE_DEBS += $(NEPHOS_SAI) $(NEPHOS_SAI_DEV) endif $(NEPHOS_SAI_DEV)_DEPENDS += $(NEPHOS_SAI) +$(NEPHOS_SAI_DEV)_CONFLICTS += $(LIBSAIVS_DEV) diff --git a/platform/p4/rules.mk b/platform/p4/rules.mk index 975dbb82ec..b33b04f43d 100644 --- a/platform/p4/rules.mk +++ b/platform/p4/rules.mk @@ -10,8 +10,8 @@ include $(PLATFORM_PATH)/libsaithrift-dev.mk SONIC_ALL += $(DOCKER_SONIC_P4) -$(LIBSAIREDIS)_DEPENDS += $(P4_SWITCH) +$(SYNCD)_DEPENDS += $(P4_SWITCH) ifeq ($(ENABLE_SYNCD_RPC),y) -$(LIBSAIREDIS)_DEPENDS += $(LIBSAITHRIFT_DEV_P4) +$(SYNCD)_DEPENDS += $(LIBSAITHRIFT_DEV_P4) endif -$(LIBSAIREDIS)_RDEPENDS += $(P4_SWITCH) +$(SYNCD)_RDEPENDS += $(P4_SWITCH) diff --git a/platform/vs/syncd-vs.mk b/platform/vs/syncd-vs.mk index 49035aaf95..22b34fbcaa 100644 --- a/platform/vs/syncd-vs.mk +++ b/platform/vs/syncd-vs.mk @@ -1,8 +1,5 @@ $(LIBSAIREDIS)_DPKG_TARGET = binary-syncd-vs -# inject libsaivs and libsaivs_dev to swss build dependency -$(SWSS)_DEPENDS += $(LIBSAIVS) $(LIBSAIVS_DEV) - SYNCD_VS = syncd-vs_1.0.0_amd64.deb $(SYNCD_VS)_RDEPENDS += $(LIBSAIREDIS) $(LIBSAIMETADATA) $(LIBSAIVS) $(eval $(call add_derived_package,$(LIBSAIREDIS),$(SYNCD_VS))) diff --git a/rules/sairedis.mk b/rules/sairedis.mk index fd026541a4..8e6aff2f7d 100644 --- a/rules/sairedis.mk +++ b/rules/sairedis.mk @@ -1,16 +1,10 @@ # sairedis package LIBSAIREDIS = libsairedis_1.0.0_$(CONFIGURED_ARCH).deb +$(LIBSAIREDIS)_DPKG_TARGET = binary-sairedis $(LIBSAIREDIS)_SRC_PATH = $(SRC_PATH)/sonic-sairedis $(LIBSAIREDIS)_DEPENDS += $(LIBSWSSCOMMON_DEV) $(LIBSAIREDIS)_RDEPENDS += $(LIBSWSSCOMMON) -ifneq ($(ENABLE_SYNCD_RPC),y) -$(LIBSAIREDIS)_DPKG_TARGET = binary-syncd -else -# Inject libthrift build dependency for RPC build -$(LIBSAIREDIS)_DEPENDS += $(LIBSWSSCOMMON_DEV) $(LIBTHRIFT_DEV) -$(LIBSAIREDIS)_DPKG_TARGET = binary-syncd-rpc -endif $(LIBSAIREDIS)_DEB_BUILD_OPTIONS = nocheck SONIC_DPKG_DEBS += $(LIBSAIREDIS) @@ -23,18 +17,6 @@ $(eval $(call add_derived_package,$(LIBSAIREDIS),$(LIBSAIVS))) LIBSAIVS_DEV = libsaivs-dev_1.0.0_$(CONFIGURED_ARCH).deb $(eval $(call add_derived_package,$(LIBSAIREDIS),$(LIBSAIVS_DEV))) -ifneq ($(CONFIGURED_PLATFORM),vs) -SYNCD = syncd_1.0.0_$(CONFIGURED_ARCH).deb -$(SYNCD)_RDEPENDS += $(LIBSAIREDIS) $(LIBSAIMETADATA) -$(eval $(call add_derived_package,$(LIBSAIREDIS),$(SYNCD))) - -ifeq ($(ENABLE_SYNCD_RPC),y) -SYNCD_RPC = syncd-rpc_1.0.0_$(CONFIGURED_ARCH).deb -$(SYNCD_RPC)_RDEPENDS += $(LIBSAIREDIS) $(LIBSAIMETADATA) -$(eval $(call add_derived_package,$(LIBSAIREDIS),$(SYNCD_RPC))) -endif -endif - LIBSAIMETADATA = libsaimetadata_1.0.0_$(CONFIGURED_ARCH).deb $(eval $(call add_derived_package,$(LIBSAIREDIS),$(LIBSAIMETADATA))) @@ -52,20 +34,6 @@ $(LIBSAIVS_DBG)_DEPENDS += $(LIBSAIVS) $(LIBSAIVS_DBG)_RDEPENDS += $(LIBSAIVS) $(eval $(call add_derived_package,$(LIBSAIREDIS),$(LIBSAIVS_DBG))) -ifneq ($(CONFIGURED_PLATFORM),vs) -SYNCD_DBG = syncd-dbg_1.0.0_$(CONFIGURED_ARCH).deb -$(SYNCD_DBG)_DEPENDS += $(SYNCD) -$(SYNCD_DBG)_RDEPENDS += $(SYNCD) -$(eval $(call add_derived_package,$(LIBSAIREDIS),$(SYNCD_DBG))) - -ifeq ($(ENABLE_SYNCD_RPC),y) -SYNCD_RPC_DBG = syncd-rpc-dbg_1.0.0_$(CONFIGURED_ARCH).deb -$(SYNCD_RPC_DBG)_DEPENDS += $(SYNCD_RPC) -$(SYNCD_RPC_DBG)_RDEPENDS += $(SYNCD_RPC) -$(eval $(call add_derived_package,$(LIBSAIREDIS),$(SYNCD_RPC_DBG))) -endif -endif - LIBSAIMETADATA_DBG = libsaimetadata-dbg_1.0.0_$(CONFIGURED_ARCH).deb $(LIBSAIMETADATA_DBG)_DEPENDS += $(LIBSAIMETADATA) $(LIBSAIMETADATA_DBG)_RDEPENDS += $(LIBSAIMETADATA) @@ -75,4 +43,3 @@ $(eval $(call add_derived_package,$(LIBSAIREDIS),$(LIBSAIMETADATA_DBG))) # are archived into debug one image to facilitate debugging. # DBG_SRC_ARCHIVE += sonic-sairedis - diff --git a/rules/swss.mk b/rules/swss.mk index b8106757ac..bb4293c2d9 100644 --- a/rules/swss.mk +++ b/rules/swss.mk @@ -3,7 +3,9 @@ SWSS = swss_1.0.0_$(CONFIGURED_ARCH).deb $(SWSS)_SRC_PATH = $(SRC_PATH)/sonic-swss $(SWSS)_DEPENDS += $(LIBSAIREDIS_DEV) $(LIBSAIMETADATA_DEV) $(LIBTEAM_DEV) \ - $(LIBTEAMDCTL) $(LIBTEAM_UTILS) $(LIBSWSSCOMMON_DEV) + $(LIBTEAMDCTL) $(LIBTEAM_UTILS) $(LIBSWSSCOMMON_DEV) \ + $(LIBSAIVS) $(LIBSAIVS_DEV) + $(SWSS)_RDEPENDS += $(LIBSAIREDIS) $(LIBSAIMETADATA) $(LIBTEAM) \ $(LIBTEAMDCTL) $(LIBSWSSCOMMON) $(PYTHON_SWSSCOMMON) SONIC_DPKG_DEBS += $(SWSS) diff --git a/rules/syncd.dep b/rules/syncd.dep new file mode 100644 index 0000000000..d9f40a8a02 --- /dev/null +++ b/rules/syncd.dep @@ -0,0 +1,20 @@ + +ifneq ($(CONFIGURED_PLATFORM),vs) + +#DPKG FRK +SPATH := $($(SYNCD)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/syncd.mk rules/syncd.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) + +SMDEP_PATHS := $(SPATH) $(SPATH)/SAI $(SPATH)/SAI/bm/behavioral-model $(SPATH)/SAI/test/ptf $(SPATH)/SAI/test/saithrift/ctypesgen +$(foreach path, $(SMDEP_PATHS), $(eval $(path) :=$(filter-out $(SMDEP_PATHS),$(addprefix $(path)/, \ + $(shell cd $(path) && git ls-files | grep -v " "))))) + + +$(SYNCD)_CACHE_MODE := GIT_CONTENT_SHA +$(SYNCD)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SYNCD)_DEP_FILES := $(DEP_FILES) +$(SYNCD)_SMDEP_FILES := $(foreach path, $(SMDEP_PATHS), $($(path))) +$(SYNCD)_SMDEP_PATHS := $(SMDEP_PATHS) + +endif diff --git a/rules/syncd.mk b/rules/syncd.mk new file mode 100644 index 0000000000..2b7007d84d --- /dev/null +++ b/rules/syncd.mk @@ -0,0 +1,36 @@ +# only used for non-vs platforms + +ifneq ($(CONFIGURED_PLATFORM),vs) + +SYNCD = syncd_1.0.0_$(CONFIGURED_ARCH).deb +$(SYNCD)_RDEPENDS += $(LIBSAIREDIS) $(LIBSAIMETADATA) +$(SYNCD)_DPKG_TARGET = binary-syncd +$(SYNCD)_SRC_PATH = $(SRC_PATH)/sonic-sairedis +$(SYNCD)_DEPENDS += $(LIBSWSSCOMMON_DEV) $(LIBSAIREDIS) +$(SYNCD)_RDEPENDS += $(LIBSWSSCOMMON) +$(SYNCD)_DEB_BUILD_OPTIONS = nocheck +SONIC_DPKG_DEBS += $(SYNCD) + +ifeq ($(ENABLE_SYNCD_RPC),y) +SYNCD_RPC = syncd-rpc_1.0.0_$(CONFIGURED_ARCH).deb +$(SYNCD_RPC)_RDEPENDS += $(LIBSAIREDIS) $(LIBSAIMETADATA) +$(eval $(call add_derived_package,$(SYNCD),$(SYNCD_RPC))) + +# Inject libthrift build dependency for RPC build +$(SYNCD)_DEPENDS += $(LIBSWSSCOMMON_DEV) $(LIBTHRIFT_DEV) +$(SYNCD)_DPKG_TARGET = binary-syncd-rpc +endif + +SYNCD_DBG = syncd-dbg_1.0.0_$(CONFIGURED_ARCH).deb +$(SYNCD_DBG)_DEPENDS += $(SYNCD) +$(SYNCD_DBG)_RDEPENDS += $(SYNCD) +$(eval $(call add_derived_package,$(SYNCD),$(SYNCD_DBG))) + +ifeq ($(ENABLE_SYNCD_RPC),y) +SYNCD_RPC_DBG = syncd-rpc-dbg_1.0.0_$(CONFIGURED_ARCH).deb +$(SYNCD_RPC_DBG)_DEPENDS += $(SYNCD_RPC) +$(SYNCD_RPC_DBG)_RDEPENDS += $(SYNCD_RPC) +$(eval $(call add_derived_package,$(SYNCD),$(SYNCD_RPC_DBG))) +endif + +endif diff --git a/slave.mk b/slave.mk index a03c28f448..cd22d665cf 100644 --- a/slave.mk +++ b/slave.mk @@ -479,7 +479,7 @@ SONIC_INSTALL_TARGETS = $(addsuffix -install,$(addprefix $(DEBS_PATH)/, \ $(SONIC_PYTHON_STDEB_DEBS) \ $(SONIC_DERIVED_DEBS) \ $(SONIC_EXTRA_DEBS))) -$(SONIC_INSTALL_TARGETS) : $(DEBS_PATH)/%-install : .platform $$(addsuffix -install,$$(addprefix $(DEBS_PATH)/,$$($$*_DEPENDS))) $(DEBS_PATH)/$$* +$(SONIC_INSTALL_TARGETS) : $(DEBS_PATH)/%-install : .platform $$(addsuffix -install,$$(addprefix $(DEBS_PATH)/,$$($$*_DEPENDS))) $(DEBS_PATH)/$$* $$(addsuffix -uninstall,$$(addprefix $(DEBS_PATH)/,$$($$*_CONFLICTS))) $(HEADER) [ -f $(DEBS_PATH)/$* ] || { echo $(DEBS_PATH)/$* does not exist $(LOG) && false $(LOG) } # put a lock here because dpkg does not allow installing packages in parallel @@ -490,6 +490,27 @@ $(SONIC_INSTALL_TARGETS) : $(DEBS_PATH)/%-install : .platform $$(addsuffix -inst done $(FOOTER) +# Targets for installing debian packages prior to build one that depends on them +SONIC_UNINSTALL_TARGETS = $(addsuffix -uninstall,$(addprefix $(DEBS_PATH)/, \ + $(SONIC_ONLINE_DEBS) \ + $(SONIC_COPY_DEBS) \ + $(SONIC_MAKE_DEBS) \ + $(SONIC_DPKG_DEBS) \ + $(SONIC_PYTHON_STDEB_DEBS) \ + $(SONIC_DERIVED_DEBS) \ + $(SONIC_EXTRA_DEBS))) + +$(SONIC_UNINSTALL_TARGETS) : $(DEBS_PATH)/%-uninstall : .platform + $(HEADER) + [ -f $(DEBS_PATH)/$* ] || { echo $(DEBS_PATH)/$* does not exist $(LOG) && false $(LOG) } + # put a lock here because dpkg does not allow installing packages in parallel + while true; do + if mkdir $(DEBS_PATH)/dpkg_lock &> /dev/null; then + { sudo DEBIAN_FRONTEND=noninteractive dpkg -P $(firstword $(subst _, ,$(basename $*))) $(LOG) && rm -d $(DEBS_PATH)/dpkg_lock && break; } || { rm -d $(DEBS_PATH)/dpkg_lock && exit 1 ; } + fi + done + $(FOOTER) + ############################################################################### ## Python packages ############################################################################### diff --git a/src/sonic-sairedis b/src/sonic-sairedis index ef72159552..ccbb3bcc87 160000 --- a/src/sonic-sairedis +++ b/src/sonic-sairedis @@ -1 +1 @@ -Subproject commit ef721595520d827277610d11e24082934afc4df8 +Subproject commit ccbb3bcc877cff271104ed428d9aadc4438dd73a From eebca9103ccbdfcff739226acd19c8cb55dbad5c Mon Sep 17 00:00:00 2001 From: paavaanan Date: Fri, 3 Jul 2020 10:38:04 +0530 Subject: [PATCH 16/23] [Dell]: DellEMC S6100 disable pericom/xlinx chipset (#4868) - Xilinx/pericom peripherals are not actively used in DellEMC S6100 switch. - These peripherals are throwing PCIE corrected messages in some of the units and filling syslog. - Since it is not usable disabling it at startup. --- .../s6100/scripts/s6100_platform.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_platform.sh b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_platform.sh index 34dc0daa4f..1f65045bd3 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_platform.sh +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_platform.sh @@ -18,6 +18,8 @@ remove_python_api_package() { if [[ "$1" == "init" ]]; then + + pericom="/sys/bus/pci/devices/0000:08:00.0" modprobe i2c-dev modprobe i2c-mux-pca954x force_deselect_on_exit=1 modprobe dell_ich @@ -26,6 +28,10 @@ if [[ "$1" == "init" ]]; then modprobe nvram systemctl start s6100-reboot-cause.service + # Disable pericom/xilinx + echo 1 > /sys/bus/pci/devices/0000:02:00.0/remove + [ -d $pericom ] && echo 1 > $pericom/remove + # Disable Watchdog Timer if [[ -e /usr/local/bin/platform_watchdog_disable.sh ]]; then /usr/local/bin/platform_watchdog_disable.sh From 4240c8c22d962dd25747931e3a35710b05a03c51 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Thu, 2 Jul 2020 22:38:31 -0700 Subject: [PATCH 17/23] [sonic-platform-daemons] Update submodule (#4887) * src/sonic-platform-daemons abe115e...9b8bfa1 (1): > [xcvrd] Update key names in 'get_media_settings_value()' (#63) --- src/sonic-platform-daemons | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-platform-daemons b/src/sonic-platform-daemons index abe115e6a6..9b8bfa10b2 160000 --- a/src/sonic-platform-daemons +++ b/src/sonic-platform-daemons @@ -1 +1 @@ -Subproject commit abe115e6a680c76d09dea04e6aab1d16876aed7a +Subproject commit 9b8bfa10b2ba57129edfe5447880afea02b5692d From 0a260b7edadaac647f6a47844499d59a43f874d2 Mon Sep 17 00:00:00 2001 From: lguohan Date: Fri, 3 Jul 2020 14:31:31 -0700 Subject: [PATCH 18/23] [docker-orchagent]: upgrade docker-orchagent to buster (#4889) also update submodule * 01f810f 2020-07-02 | fix compiling issue for gcc8.3 (#1339) [lguohan] * 9b13120 2020-07-03 | Fix in script to avoid orchagent crash when port down followed by fdb delete (#1340) [rupesh-k] * 9b01844 2020-07-01 | [qosorch] Update QoS scheduler params for shaping features (#1296) [Michael Li] * 86b5e99 2020-07-02 | [mirrororch] Port Mirroring implementation (#1314) [rupesh-k] * c05601c 2020-06-24 | [portsyncd]: add debug message if a port cannot be found in port able (#1328) [lguohan] * a0b6412 2020-06-23 | COPP_DEL_fix: DEL for one trap group from SONIC is resetting all the trap IDs (#1273) [SinghMinu] Signed-off-by: Guohan Lu --- dockers/docker-orchagent/Dockerfile.j2 | 2 +- rules/docker-orchagent.mk | 8 +++----- src/sonic-swss | 2 +- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/dockers/docker-orchagent/Dockerfile.j2 b/dockers/docker-orchagent/Dockerfile.j2 index d08ecdb49d..2584a34e1e 100755 --- a/dockers/docker-orchagent/Dockerfile.j2 +++ b/dockers/docker-orchagent/Dockerfile.j2 @@ -1,5 +1,5 @@ {% from "dockers/dockerfile-macros.j2" import install_debian_packages, install_python_wheels, copy_files %} -FROM docker-config-engine-stretch +FROM docker-config-engine-buster ARG docker_container_name RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf diff --git a/rules/docker-orchagent.mk b/rules/docker-orchagent.mk index 4d63502ebb..e60bc81914 100644 --- a/rules/docker-orchagent.mk +++ b/rules/docker-orchagent.mk @@ -6,23 +6,21 @@ DOCKER_ORCHAGENT_DBG = $(DOCKER_ORCHAGENT_STEM)-$(DBG_IMAGE_MARK).gz $(DOCKER_ORCHAGENT)_DEPENDS += $(SWSS) -$(DOCKER_ORCHAGENT)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_DEPENDS) +$(DOCKER_ORCHAGENT)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_DEPENDS) $(DOCKER_ORCHAGENT)_DBG_DEPENDS += $(SWSS_DBG) \ $(LIBSWSSCOMMON_DBG) \ $(LIBSAIREDIS_DBG) -$(DOCKER_ORCHAGENT)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_IMAGE_PACKAGES) +$(DOCKER_ORCHAGENT)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_IMAGE_PACKAGES) $(DOCKER_ORCHAGENT)_PATH = $(DOCKERS_PATH)/$(DOCKER_ORCHAGENT_STEM) -$(DOCKER_ORCHAGENT)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_STRETCH) +$(DOCKER_ORCHAGENT)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_BUSTER) SONIC_DOCKER_IMAGES += $(DOCKER_ORCHAGENT) -SONIC_STRETCH_DOCKERS += $(DOCKER_ORCHAGENT) SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_ORCHAGENT) SONIC_DOCKER_DBG_IMAGES += $(DOCKER_ORCHAGENT_DBG) -SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_ORCHAGENT_DBG) SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_ORCHAGENT_DBG) $(DOCKER_ORCHAGENT)_CONTAINER_NAME = swss diff --git a/src/sonic-swss b/src/sonic-swss index 17a2f93a54..01f810f43e 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit 17a2f93a545b8669e44a62231c340ba518272ed7 +Subproject commit 01f810f43e71a570f7821c63f8ac030c03f88150 From 90dcbe13f21ce76e95402b2a02a1d5854cb00163 Mon Sep 17 00:00:00 2001 From: Volodymyr Boiko <66446128+vboykox@users.noreply.github.com> Date: Sat, 4 Jul 2020 00:33:12 +0300 Subject: [PATCH 19/23] [barefoot][SAI v1.6.3] Update SAI and platform packages to 20200701 (#4890) Signed-off-by: Volodymyr Boyko --- platform/barefoot/bfn-platform.mk | 2 +- platform/barefoot/bfn-sai.mk | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/barefoot/bfn-platform.mk b/platform/barefoot/bfn-platform.mk index 99ee7592f3..d563db6745 100644 --- a/platform/barefoot/bfn-platform.mk +++ b/platform/barefoot/bfn-platform.mk @@ -1,4 +1,4 @@ -BFN_PLATFORM = bfnplatform_20200618_deb9.deb +BFN_PLATFORM = bfnplatform_20200701_deb9.deb $(BFN_PLATFORM)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/dev/$(BFN_PLATFORM)" SONIC_ONLINE_DEBS += $(BFN_PLATFORM) diff --git a/platform/barefoot/bfn-sai.mk b/platform/barefoot/bfn-sai.mk index 3ba9516203..05e70282dd 100644 --- a/platform/barefoot/bfn-sai.mk +++ b/platform/barefoot/bfn-sai.mk @@ -1,4 +1,4 @@ -BFN_SAI = bfnsdk_20200618_deb9.deb +BFN_SAI = bfnsdk_20200701_deb9.deb $(BFN_SAI)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/dev/$(BFN_SAI)" $(BFN_SAI)_DEPENDS += $(LIBNL_GENL3_DEV) From 405033b0a0d55ab7172870d65670f47b930d61d3 Mon Sep 17 00:00:00 2001 From: xumia <59720581+xumia@users.noreply.github.com> Date: Sat, 4 Jul 2020 21:40:02 +0800 Subject: [PATCH 20/23] Fix dpkg cache hash value relative to file path issue (#4894) --- Makefile.cache | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.cache b/Makefile.cache index fb79e51e7f..5422b59592 100644 --- a/Makefile.cache +++ b/Makefile.cache @@ -68,7 +68,7 @@ # Run the 'touch cache.skip.common' command in the base directory to exclude the common files from caching SONIC_COMMON_FILES_LIST := $(if $(wildcard cache.skip.common),, .platform slave.mk rules/functions Makefile.cache) SONIC_COMMON_FLAGS_LIST := $(CONFIGURED_PLATFORM) \ - $(SONIC_DPKG_CACHE_SOURCE) $(SONIC_DEBUGGING_ON) \ + $(SONIC_DEBUGGING_ON) \ $(SONIC_PROFILING_ON) $(SONIC_ENABLE_SYNCD_RPC) SONIC_COMMON_DPKG_LIST := debian/control debian/changelog debian/rules \ debian/compat debian/install debian/copyright From 20698aa57b05ec490b14c6b0addc1bd71b03e650 Mon Sep 17 00:00:00 2001 From: zzhiyuan Date: Sun, 5 Jul 2020 00:11:42 -0700 Subject: [PATCH 21/23] Skip thermalctld for arista platforms (#4893) thermalctld throwing error messages because it is not yet fully configured, disabling it for now on arista platforms. Co-authored-by: Zhi Yuan Carl Zhao --- .../arista/x86_64-arista_7050_qx32/pmon_daemon_control.json | 1 + .../arista/x86_64-arista_7050_qx32s/pmon_daemon_control.json | 1 + .../arista/x86_64-arista_7050cx3_32s/pmon_daemon_control.json | 1 + .../arista/x86_64-arista_7060_cx32s/pmon_daemon_control.json | 1 + .../arista/x86_64-arista_7060cx2_32s/pmon_daemon_control.json | 1 + .../arista/x86_64-arista_7060px4_32/pmon_daemon_control.json | 1 + device/arista/x86_64-arista_7170_32c/pmon_daemon_control.json | 1 + .../arista/x86_64-arista_7170_32cd/pmon_daemon_control.json | 1 + device/arista/x86_64-arista_7170_64c/pmon_daemon_control.json | 1 + .../arista/x86_64-arista_7260cx3_64/pmon_daemon_control.json | 1 + .../x86_64-arista_7280cr3_32p4/pmon_daemon_control.json | 1 + .../pmon_daemon_control_skip_thermalctld.json | 4 ++++ 12 files changed, 15 insertions(+) create mode 120000 device/arista/x86_64-arista_7050_qx32/pmon_daemon_control.json create mode 120000 device/arista/x86_64-arista_7050_qx32s/pmon_daemon_control.json create mode 120000 device/arista/x86_64-arista_7050cx3_32s/pmon_daemon_control.json create mode 120000 device/arista/x86_64-arista_7060_cx32s/pmon_daemon_control.json create mode 120000 device/arista/x86_64-arista_7060cx2_32s/pmon_daemon_control.json create mode 120000 device/arista/x86_64-arista_7060px4_32/pmon_daemon_control.json create mode 120000 device/arista/x86_64-arista_7170_32c/pmon_daemon_control.json create mode 120000 device/arista/x86_64-arista_7170_32cd/pmon_daemon_control.json create mode 120000 device/arista/x86_64-arista_7170_64c/pmon_daemon_control.json create mode 120000 device/arista/x86_64-arista_7260cx3_64/pmon_daemon_control.json create mode 120000 device/arista/x86_64-arista_7280cr3_32p4/pmon_daemon_control.json create mode 100644 device/arista/x86_64-arista_common/pmon_daemon_control_skip_thermalctld.json diff --git a/device/arista/x86_64-arista_7050_qx32/pmon_daemon_control.json b/device/arista/x86_64-arista_7050_qx32/pmon_daemon_control.json new file mode 120000 index 0000000000..2322ef7a22 --- /dev/null +++ b/device/arista/x86_64-arista_7050_qx32/pmon_daemon_control.json @@ -0,0 +1 @@ +../x86_64-arista_common/pmon_daemon_control_skip_thermalctld.json \ No newline at end of file diff --git a/device/arista/x86_64-arista_7050_qx32s/pmon_daemon_control.json b/device/arista/x86_64-arista_7050_qx32s/pmon_daemon_control.json new file mode 120000 index 0000000000..2322ef7a22 --- /dev/null +++ b/device/arista/x86_64-arista_7050_qx32s/pmon_daemon_control.json @@ -0,0 +1 @@ +../x86_64-arista_common/pmon_daemon_control_skip_thermalctld.json \ No newline at end of file diff --git a/device/arista/x86_64-arista_7050cx3_32s/pmon_daemon_control.json b/device/arista/x86_64-arista_7050cx3_32s/pmon_daemon_control.json new file mode 120000 index 0000000000..2322ef7a22 --- /dev/null +++ b/device/arista/x86_64-arista_7050cx3_32s/pmon_daemon_control.json @@ -0,0 +1 @@ +../x86_64-arista_common/pmon_daemon_control_skip_thermalctld.json \ No newline at end of file diff --git a/device/arista/x86_64-arista_7060_cx32s/pmon_daemon_control.json b/device/arista/x86_64-arista_7060_cx32s/pmon_daemon_control.json new file mode 120000 index 0000000000..2322ef7a22 --- /dev/null +++ b/device/arista/x86_64-arista_7060_cx32s/pmon_daemon_control.json @@ -0,0 +1 @@ +../x86_64-arista_common/pmon_daemon_control_skip_thermalctld.json \ No newline at end of file diff --git a/device/arista/x86_64-arista_7060cx2_32s/pmon_daemon_control.json b/device/arista/x86_64-arista_7060cx2_32s/pmon_daemon_control.json new file mode 120000 index 0000000000..2322ef7a22 --- /dev/null +++ b/device/arista/x86_64-arista_7060cx2_32s/pmon_daemon_control.json @@ -0,0 +1 @@ +../x86_64-arista_common/pmon_daemon_control_skip_thermalctld.json \ No newline at end of file diff --git a/device/arista/x86_64-arista_7060px4_32/pmon_daemon_control.json b/device/arista/x86_64-arista_7060px4_32/pmon_daemon_control.json new file mode 120000 index 0000000000..2322ef7a22 --- /dev/null +++ b/device/arista/x86_64-arista_7060px4_32/pmon_daemon_control.json @@ -0,0 +1 @@ +../x86_64-arista_common/pmon_daemon_control_skip_thermalctld.json \ No newline at end of file diff --git a/device/arista/x86_64-arista_7170_32c/pmon_daemon_control.json b/device/arista/x86_64-arista_7170_32c/pmon_daemon_control.json new file mode 120000 index 0000000000..2322ef7a22 --- /dev/null +++ b/device/arista/x86_64-arista_7170_32c/pmon_daemon_control.json @@ -0,0 +1 @@ +../x86_64-arista_common/pmon_daemon_control_skip_thermalctld.json \ No newline at end of file diff --git a/device/arista/x86_64-arista_7170_32cd/pmon_daemon_control.json b/device/arista/x86_64-arista_7170_32cd/pmon_daemon_control.json new file mode 120000 index 0000000000..2322ef7a22 --- /dev/null +++ b/device/arista/x86_64-arista_7170_32cd/pmon_daemon_control.json @@ -0,0 +1 @@ +../x86_64-arista_common/pmon_daemon_control_skip_thermalctld.json \ No newline at end of file diff --git a/device/arista/x86_64-arista_7170_64c/pmon_daemon_control.json b/device/arista/x86_64-arista_7170_64c/pmon_daemon_control.json new file mode 120000 index 0000000000..2322ef7a22 --- /dev/null +++ b/device/arista/x86_64-arista_7170_64c/pmon_daemon_control.json @@ -0,0 +1 @@ +../x86_64-arista_common/pmon_daemon_control_skip_thermalctld.json \ No newline at end of file diff --git a/device/arista/x86_64-arista_7260cx3_64/pmon_daemon_control.json b/device/arista/x86_64-arista_7260cx3_64/pmon_daemon_control.json new file mode 120000 index 0000000000..2322ef7a22 --- /dev/null +++ b/device/arista/x86_64-arista_7260cx3_64/pmon_daemon_control.json @@ -0,0 +1 @@ +../x86_64-arista_common/pmon_daemon_control_skip_thermalctld.json \ No newline at end of file diff --git a/device/arista/x86_64-arista_7280cr3_32p4/pmon_daemon_control.json b/device/arista/x86_64-arista_7280cr3_32p4/pmon_daemon_control.json new file mode 120000 index 0000000000..2322ef7a22 --- /dev/null +++ b/device/arista/x86_64-arista_7280cr3_32p4/pmon_daemon_control.json @@ -0,0 +1 @@ +../x86_64-arista_common/pmon_daemon_control_skip_thermalctld.json \ No newline at end of file diff --git a/device/arista/x86_64-arista_common/pmon_daemon_control_skip_thermalctld.json b/device/arista/x86_64-arista_common/pmon_daemon_control_skip_thermalctld.json new file mode 100644 index 0000000000..75db6d9755 --- /dev/null +++ b/device/arista/x86_64-arista_common/pmon_daemon_control_skip_thermalctld.json @@ -0,0 +1,4 @@ +{ + "skip_thermalctld": true +} + From 31baf3817378e890a5e51cae144833613c1180f9 Mon Sep 17 00:00:00 2001 From: arlakshm <55814491+arlakshm@users.noreply.github.com> Date: Sun, 5 Jul 2020 22:22:31 -0700 Subject: [PATCH 22/23] "[config]: Multi ASIC loopback changes (#4895) Resubmitting the changes for (#4825) with fixes for sonic-bgpcdgd test failures Signed-off-by: Arvindsrinivasan Lakshmi Narasimhan --- .../docker-fpm-frr/frr/bgpd/bgpd.main.conf.j2 | 16 +++++++- src/sonic-config-engine/minigraph.py | 32 +++++++++++---- src/sonic-config-engine/sonic-cfggen | 3 ++ src/sonic-config-engine/sonic_device_util.py | 16 ++++++-- .../tests/multi_npu_data/sample-minigraph.xml | 40 +++++++++++++++++-- .../tests/test_multinpu_cfggen.py | 29 ++++++++++++++ 6 files changed, 120 insertions(+), 16 deletions(-) diff --git a/dockers/docker-fpm-frr/frr/bgpd/bgpd.main.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/bgpd.main.conf.j2 index ef98dcf9f1..5fe7a2b010 100644 --- a/dockers/docker-fpm-frr/frr/bgpd/bgpd.main.conf.j2 +++ b/dockers/docker-fpm-frr/frr/bgpd/bgpd.main.conf.j2 @@ -15,7 +15,7 @@ ipv6 prefix-list PL_LoopbackV6 permit {{ get_ipv6_loopback_address(LOOPBACK_INTE {% endif %} ! ! -{% if DEVICE_METADATA['localhost']['sub_role'] == 'FrontEnd' %} +{% if DEVICE_METADATA['localhost']['sub_role'] == 'FrontEnd' or DEVICE_METADATA['localhost']['sub_role'] == 'BackEnd' %} route-map HIDE_INTERNAL permit 10 set community local-AS ! @@ -38,16 +38,30 @@ router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} {% endif %} ! {# set router-id #} +{% if multi_asic() %} + bgp router-id {{ get_ipv4_loopback_address(LOOPBACK_INTERFACE, "Loopback4096") | ip }} +{% else %} bgp router-id {{ get_ipv4_loopback_address(LOOPBACK_INTERFACE, "Loopback0") | ip }} +{% endif %} ! {# advertise loopback #} network {{ get_ipv4_loopback_address(LOOPBACK_INTERFACE, "Loopback0") | ip }}/32 +{% if multi_asic() %} + network {{ get_ipv4_loopback_address(LOOPBACK_INTERFACE, "Loopback4096") | ip }}/32 route-map HIDE_INTERNAL +{% endif %} ! {% if get_ipv6_loopback_address(LOOPBACK_INTERFACE, "Loopback0") != 'None' %} address-family ipv6 network {{ get_ipv6_loopback_address(LOOPBACK_INTERFACE, "Loopback0") | ip }}/64 exit-address-family {% endif %} +{% if multi_asic() %} +{% if get_ipv6_loopback_address(LOOPBACK_INTERFACE, "Loopback4096") != 'None' %} + address-family ipv6 + network {{ get_ipv6_loopback_address(LOOPBACK_INTERFACE, "Loopback4096") | ip }}/64 route-map HIDE_INTERNAL + exit-address-family +{% endif %} +{% endif %} {% endblock bgp_init %} ! {% block vlan_advertisement %} diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index 79e553e019..2fe6999872 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -251,6 +251,15 @@ def parse_asic_png(png, asic_name, hostname): devices[name] = device_data return (neighbors, devices, port_speeds) +def parse_loopback_intf(child): + lointfs = child.find(str(QName(ns, "LoopbackIPInterfaces"))) + lo_intfs = {} + for lointf in lointfs.findall(str(QName(ns1, "LoopbackIPInterface"))): + intfname = lointf.find(str(QName(ns, "AttachTo"))).text + ipprefix = lointf.find(str(QName(ns1, "PrefixStr"))).text + lo_intfs[(intfname, ipprefix)] = {} + return lo_intfs + def parse_dpg(dpg, hname): aclintfs = None mgmtintfs = None @@ -269,7 +278,6 @@ def parse_dpg(dpg, hname): """ if mgmtintfs is None and child.find(str(QName(ns, "ManagementIPInterfaces"))) is not None: mgmtintfs = child.find(str(QName(ns, "ManagementIPInterfaces"))) - hostname = child.find(str(QName(ns, "Hostname"))) if hostname.text.lower() != hname.lower(): continue @@ -290,12 +298,7 @@ def parse_dpg(dpg, hname): ipprefix = ipintf.find(str(QName(ns, "Prefix"))).text intfs[(intfname, ipprefix)] = {} - lointfs = child.find(str(QName(ns, "LoopbackIPInterfaces"))) - lo_intfs = {} - for lointf in lointfs.findall(str(QName(ns1, "LoopbackIPInterface"))): - intfname = lointf.find(str(QName(ns, "AttachTo"))).text - ipprefix = lointf.find(str(QName(ns1, "PrefixStr"))).text - lo_intfs[(intfname, ipprefix)] = {} + lo_intfs = parse_loopback_intf(child) mvrfConfigs = child.find(str(QName(ns, "MgmtVrfConfigs"))) mvrf = {} @@ -452,6 +455,13 @@ def parse_dpg(dpg, hname): return intfs, lo_intfs, mvrf, mgmt_intf, vlans, vlan_members, pcs, pc_members, acls, vni return None, None, None, None, None, None, None, None, None, None +def parse_host_loopback(dpg, hname): + for child in dpg: + hostname = child.find(str(QName(ns, "Hostname"))) + if hostname.text.lower() != hname.lower(): + continue + lo_intfs = parse_loopback_intf(child) + return lo_intfs def parse_cpg(cpg, hname): bgp_sessions = {} @@ -826,6 +836,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw cloudtype = None hostname = None linkmetas = {} + host_lo_intfs = None # hostname is the asic_name, get the asic_id from the asic_name if asic_name is not None: @@ -867,6 +878,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw else: if child.tag == str(QName(ns, "DpgDec")): (intfs, lo_intfs, mvrf, mgmt_intf, vlans, vlan_members, pcs, pc_members, acls, vni) = parse_dpg(child, asic_name) + host_lo_intfs = parse_host_loopback(child, hostname) elif child.tag == str(QName(ns, "CpgDec")): (bgp_sessions, bgp_asn, bgp_peers_with_range, bgp_monitors) = parse_cpg(child, asic_name) enable_internal_bgp_session(bgp_sessions, filename, asic_name) @@ -930,6 +942,12 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw for lo_intf in lo_intfs: results['LOOPBACK_INTERFACE'][lo_intf] = lo_intfs[lo_intf] results['LOOPBACK_INTERFACE'][lo_intf[0]] = {} + + if host_lo_intfs is not None: + for host_lo_intf in host_lo_intfs: + results['LOOPBACK_INTERFACE'][host_lo_intf] = host_lo_intfs[host_lo_intf] + results['LOOPBACK_INTERFACE'][host_lo_intf[0]] = {} + results['MGMT_VRF_CONFIG'] = mvrf phyport_intfs = {} diff --git a/src/sonic-config-engine/sonic-cfggen b/src/sonic-config-engine/sonic-cfggen index 1118703458..9bda720719 100755 --- a/src/sonic-config-engine/sonic-cfggen +++ b/src/sonic-config-engine/sonic-cfggen @@ -45,6 +45,7 @@ from sonic_device_util import get_machine_info from sonic_device_util import get_platform_info from sonic_device_util import get_system_mac from sonic_device_util import get_npu_id_from_name +from sonic_device_util import is_multi_npu from config_samples import generate_sample_config from config_samples import get_available_config from swsssdk import SonicV2Connector, ConfigDBConnector, SonicDBConfig @@ -344,6 +345,8 @@ def main(): env.filters['ip_network'] = ip_network for attr in ['ip', 'network', 'prefixlen', 'netmask', 'broadcast']: env.filters[attr] = partial(prefix_attr, attr) + # Pass the is_multi_npu function as global + env.globals['multi_asic'] = is_multi_npu template = env.get_template(template_file) print(template.render(sort_data(data))) diff --git a/src/sonic-config-engine/sonic_device_util.py b/src/sonic-config-engine/sonic_device_util.py index 5984a7047f..ddfa751250 100644 --- a/src/sonic-config-engine/sonic_device_util.py +++ b/src/sonic-config-engine/sonic_device_util.py @@ -44,12 +44,20 @@ def get_npu_id_from_name(npu_name): else: return None +def get_asic_conf_file_path(platform): + asic_conf_path_candidates = [] + asic_conf_path_candidates.append(os.path.join('/usr/share/sonic/platform', ASIC_CONF_FILENAME)) + if platform is not None: + asic_conf_path_candidates.append(os.path.join(SONIC_DEVICE_PATH, platform, ASIC_CONF_FILENAME)) + for asic_conf_file_path in asic_conf_path_candidates: + if os.path.isfile(asic_conf_file_path): + return asic_conf_file_path + return None + def get_num_npus(): platform = get_platform_info(get_machine_info()) - if not platform: - return 1 - asic_conf_file_path = os.path.join(SONIC_DEVICE_PATH, platform, ASIC_CONF_FILENAME) - if not os.path.isfile(asic_conf_file_path): + asic_conf_file_path = get_asic_conf_file_path(platform) + if asic_conf_file_path is None: return 1 with open(asic_conf_file_path) as asic_conf_file: for line in asic_conf_file: diff --git a/src/sonic-config-engine/tests/multi_npu_data/sample-minigraph.xml b/src/sonic-config-engine/tests/multi_npu_data/sample-minigraph.xml index 8ca17925c6..412262315b 100644 --- a/src/sonic-config-engine/tests/multi_npu_data/sample-minigraph.xml +++ b/src/sonic-config-engine/tests/multi_npu_data/sample-minigraph.xml @@ -387,12 +387,20 @@ LoopbackInterface HostIP - Loopback0 + Loopback4096 8.0.0.0/32 8.0.0.0/32 + + HostIP1 + Loopback4096 + + FD00:1::32/128 + + FD00:1::32/128 + @@ -457,12 +465,20 @@ LoopbackInterface HostIP - Loopback0 + Loopback4096 8.0.0.1/32 8.0.0.1/32 + + HostIP1 + Loopback4096 + + FD00:2::32/128 + + FD00:2::32/128 + @@ -526,12 +542,20 @@ LoopbackInterface HostIP - Loopback0 + Loopback4096 8.0.0.4/32 8.0.0.4/32 + + HostIP1 + Loopback4096 + + FD00:3::32/128 + + FD00:3::32/128 + @@ -580,12 +604,20 @@ LoopbackInterface HostIP - Loopback0 + Loopback4096 8.0.0.5/32 8.0.0.5/32 + + HostIP1 + Loopback4096 + + FD00:4::32/128 + + FD00:4::32/128 + diff --git a/src/sonic-config-engine/tests/test_multinpu_cfggen.py b/src/sonic-config-engine/tests/test_multinpu_cfggen.py index c3307b482b..7511ce9bcd 100644 --- a/src/sonic-config-engine/tests/test_multinpu_cfggen.py +++ b/src/sonic-config-engine/tests/test_multinpu_cfggen.py @@ -245,3 +245,32 @@ def test_back_end_asic_acl(self): argument = "-m {} -p {} -n asic3 --var-json \"ACL_TABLE\"".format(self.sample_graph, self.port_config[3]) output = json.loads(self.run_script(argument)) self.assertDictEqual(output, {}) + + def test_loopback_intfs(self): + argument = "-m {} --var-json \"LOOPBACK_INTERFACE\"".format(self.sample_graph) + output = json.loads(self.run_script(argument)) + self.assertDictEqual(output, {\ + "Loopback0": {}, + "Loopback0|10.1.0.32/32": {}, + "Loopback0|FC00:1::32/128": {}}) + + # The asic configuration should have 2 loopback interfaces + argument = "-m {} -n asic0 --var-json \"LOOPBACK_INTERFACE\"".format(self.sample_graph) + output = json.loads(self.run_script(argument)) + self.assertDictEqual(output, { \ + "Loopback0": {}, + "Loopback4096": {}, + "Loopback0|10.1.0.32/32": {}, + "Loopback0|FC00:1::32/128": {}, + "Loopback4096|8.0.0.0/32": {}, + "Loopback4096|FD00:1::32/128": {}}) + + argument = "-m {} -n asic3 --var-json \"LOOPBACK_INTERFACE\"".format(self.sample_graph) + output = json.loads(self.run_script(argument)) + self.assertDictEqual(output, {\ + "Loopback0": {}, + "Loopback4096": {}, + "Loopback0|10.1.0.32/32": {}, + "Loopback0|FC00:1::32/128": {}, + "Loopback4096|8.0.0.5/32": {}, + "Loopback4096|FD00:4::32/128": {}}) From 1e20620efa7a77f69e74b70a984f253067a7853b Mon Sep 17 00:00:00 2001 From: Fillmore Chen Date: Tue, 7 Jul 2020 12:03:29 +0800 Subject: [PATCH 23/23] Add platfrom snj60b0-320f (TH3) --- .../buffers.json.j2 | 2 + .../buffers_defaults_t0.j2 | 47 + .../buffers_defaults_t1.j2 | 47 + .../pg_profile_lookup.ini | 23 + .../port_config.ini | 35 + .../Alphanetworks-SNJ60B0-320F/qos.json.j2 | 228 ++ .../Alphanetworks-SNJ60B0-320F/sai.profile | 1 + .../th3-snj60b0-32x400G.config.bcm | 298 +++ .../custom_led.bin | Bin 0 -> 996 bytes .../default_sku | 1 + .../fancontrol | 9 + .../installer.conf | 4 + .../led_proc_init.soc | 11 + .../linkscan_led_fw.bin | Bin 0 -> 5636 bytes .../media_settings.json | 836 +++++++ .../platform_env.conf | 2 + .../plugins/eeprom.py | 16 + .../plugins/led_control.py | 119 + .../pmon_daemon_control.json | 4 + .../preemphasis-32x400G.soc | 1313 +++++++++++ .../sensors.conf | 13 + .../thermal_policy.json | 93 + platform/broadcom/one-image.mk | 1 + .../platform-modules-alphanetworks.mk | 7 + .../debian/changelog | 4 +- .../debian/control | 4 + .../debian/rules | 24 +- .../snj60b0-320f/classes/__init__.py | 0 .../snj60b0-320f/modules/Makefile | 8 + .../snj60b0-320f/modules/snj60b0-320f_fpga.c | 955 ++++++++ .../modules/snj60b0-320f_onie_eeprom.c | 267 +++ .../snj60b0-320f/modules/snj60b0-320f_sfp.c | 2068 +++++++++++++++++ .../snj60b0-320f/modules/yesm1300am.c | 390 ++++ .../service/snj60b0-platform-init.service | 13 + .../snj60b0-320f/setup.py | 14 + .../snj60b0-320f/sonic_platform/__init__.py | 1 + .../snj60b0-320f/sonic_platform/chassis.py | 219 ++ .../snj60b0-320f/sonic_platform/component.py | 79 + .../snj60b0-320f/sonic_platform/fan.py | 224 ++ .../snj60b0-320f/sonic_platform/fan_drawer.py | 77 + .../snj60b0-320f/sonic_platform/led.py | 94 + .../snj60b0-320f/sonic_platform/platform.py | 22 + .../snj60b0-320f/sonic_platform/psu.py | 319 +++ .../snj60b0-320f/sonic_platform/sfp.py | 925 ++++++++ .../snj60b0-320f/sonic_platform/thermal.py | 176 ++ .../sonic_platform/thermal_actions.py | 93 + .../sonic_platform/thermal_conditions.py | 77 + .../sonic_platform/thermal_infos.py | 183 ++ .../sonic_platform/thermal_manager.py | 23 + .../utils/alphanetworks_snj60b0_util.py | 521 +++++ 50 files changed, 9880 insertions(+), 10 deletions(-) create mode 100755 device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/Alphanetworks-SNJ60B0-320F/buffers.json.j2 create mode 100755 device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/Alphanetworks-SNJ60B0-320F/buffers_defaults_t0.j2 create mode 100755 device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/Alphanetworks-SNJ60B0-320F/buffers_defaults_t1.j2 create mode 100755 device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/Alphanetworks-SNJ60B0-320F/pg_profile_lookup.ini create mode 100755 device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/Alphanetworks-SNJ60B0-320F/port_config.ini create mode 100755 device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/Alphanetworks-SNJ60B0-320F/qos.json.j2 create mode 100755 device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/Alphanetworks-SNJ60B0-320F/sai.profile create mode 100755 device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/Alphanetworks-SNJ60B0-320F/th3-snj60b0-32x400G.config.bcm create mode 100755 device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/custom_led.bin create mode 100755 device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/default_sku create mode 100755 device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/fancontrol create mode 100755 device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/installer.conf create mode 100755 device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/led_proc_init.soc create mode 100755 device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/linkscan_led_fw.bin create mode 100755 device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/media_settings.json create mode 100755 device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/platform_env.conf create mode 100755 device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/plugins/eeprom.py create mode 100755 device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/plugins/led_control.py create mode 100755 device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/pmon_daemon_control.json create mode 100755 device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/preemphasis-32x400G.soc create mode 100755 device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/sensors.conf create mode 100755 device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/thermal_policy.json mode change 100644 => 100755 platform/broadcom/one-image.mk mode change 100644 => 100755 platform/broadcom/platform-modules-alphanetworks.mk mode change 100644 => 100755 platform/broadcom/sonic-platform-modules-alphanetworks/debian/changelog mode change 100644 => 100755 platform/broadcom/sonic-platform-modules-alphanetworks/debian/control create mode 100755 platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/classes/__init__.py create mode 100755 platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/modules/Makefile create mode 100755 platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/modules/snj60b0-320f_fpga.c create mode 100755 platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/modules/snj60b0-320f_onie_eeprom.c create mode 100755 platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/modules/snj60b0-320f_sfp.c create mode 100755 platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/modules/yesm1300am.c create mode 100755 platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/service/snj60b0-platform-init.service create mode 100755 platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/setup.py create mode 100755 platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/__init__.py create mode 100755 platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/chassis.py create mode 100755 platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/component.py create mode 100755 platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/fan.py create mode 100755 platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/fan_drawer.py create mode 100755 platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/led.py create mode 100755 platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/platform.py create mode 100755 platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/psu.py create mode 100755 platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/sfp.py create mode 100755 platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/thermal.py create mode 100755 platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/thermal_actions.py create mode 100755 platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/thermal_conditions.py create mode 100755 platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/thermal_infos.py create mode 100755 platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/thermal_manager.py create mode 100755 platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/utils/alphanetworks_snj60b0_util.py diff --git a/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/Alphanetworks-SNJ60B0-320F/buffers.json.j2 b/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/Alphanetworks-SNJ60B0-320F/buffers.json.j2 new file mode 100755 index 0000000000..1083a6210f --- /dev/null +++ b/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/Alphanetworks-SNJ60B0-320F/buffers.json.j2 @@ -0,0 +1,2 @@ +{%- set default_topo = 't0' %} +{%- include 'buffers_config.j2' %} diff --git a/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/Alphanetworks-SNJ60B0-320F/buffers_defaults_t0.j2 b/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/Alphanetworks-SNJ60B0-320F/buffers_defaults_t0.j2 new file mode 100755 index 0000000000..534ff46562 --- /dev/null +++ b/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/Alphanetworks-SNJ60B0-320F/buffers_defaults_t0.j2 @@ -0,0 +1,47 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "egress_lossy_pool": { + "size": "67108864", + "type": "egress", + "mode": "dynamic" + }, + "ingress_lossless_pool": { + "mode": "dynamic", + "size": "59001152", + "xoff": "7428992", + "type": "ingress" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "static_th":"67108864" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"0", + "dynamic_th":"3" + } + }, +{%- endmacro %} + +{%- macro generate_pg_profils(port_names_active) %} + "BUFFER_PG": { + "{{ port_names_active }}|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + } + }, +{%- endmacro %} + +{% macro generate_queue_buffers(port_names_active) %} + "BUFFER_QUEUE": { + "{{ port_names_active }}|0-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + } + } +{% endmacro %} + diff --git a/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/Alphanetworks-SNJ60B0-320F/buffers_defaults_t1.j2 b/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/Alphanetworks-SNJ60B0-320F/buffers_defaults_t1.j2 new file mode 100755 index 0000000000..534ff46562 --- /dev/null +++ b/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/Alphanetworks-SNJ60B0-320F/buffers_defaults_t1.j2 @@ -0,0 +1,47 @@ + +{%- set default_cable = '40m' %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "egress_lossy_pool": { + "size": "67108864", + "type": "egress", + "mode": "dynamic" + }, + "ingress_lossless_pool": { + "mode": "dynamic", + "size": "59001152", + "xoff": "7428992", + "type": "ingress" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "static_th":"67108864" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"0", + "dynamic_th":"3" + } + }, +{%- endmacro %} + +{%- macro generate_pg_profils(port_names_active) %} + "BUFFER_PG": { + "{{ port_names_active }}|0": { + "profile" : "[BUFFER_PROFILE|ingress_lossy_profile]" + } + }, +{%- endmacro %} + +{% macro generate_queue_buffers(port_names_active) %} + "BUFFER_QUEUE": { + "{{ port_names_active }}|0-6": { + "profile" : "[BUFFER_PROFILE|egress_lossy_profile]" + } + } +{% endmacro %} + diff --git a/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/Alphanetworks-SNJ60B0-320F/pg_profile_lookup.ini b/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/Alphanetworks-SNJ60B0-320F/pg_profile_lookup.ini new file mode 100755 index 0000000000..a5f3286bee --- /dev/null +++ b/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/Alphanetworks-SNJ60B0-320F/pg_profile_lookup.ini @@ -0,0 +1,23 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold xon_offset + 10000 5m 1270 0 190500 -2 2540 + 25000 5m 1270 0 190500 -2 2540 + 40000 5m 1270 0 190500 -2 2540 + 50000 5m 1270 0 190500 -2 2540 + 100000 5m 1270 0 190500 -2 2540 + 200000 5m 1270 0 190500 -2 2540 + 400000 5m 1270 0 190500 -2 2540 + 10000 40m 1270 0 190500 -2 2540 + 25000 40m 1270 0 190500 -2 2540 + 40000 40m 1270 0 190500 -2 2540 + 50000 40m 1270 0 190500 -2 2540 + 100000 40m 1270 0 190500 -2 2540 + 200000 40m 1270 0 190500 -2 2540 + 400000 40m 1270 0 190500 -2 2540 + 10000 300m 1270 0 190500 -2 2540 + 25000 300m 1270 0 190500 -2 2540 + 40000 300m 1270 0 190500 -2 2540 + 50000 300m 1270 0 190500 -2 2540 + 100000 300m 1270 0 190500 -2 2540 + 200000 300m 1270 0 190500 -2 2540 + 400000 300m 1270 0 190500 -2 2540 diff --git a/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/Alphanetworks-SNJ60B0-320F/port_config.ini b/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/Alphanetworks-SNJ60B0-320F/port_config.ini new file mode 100755 index 0000000000..f591f69f1a --- /dev/null +++ b/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/Alphanetworks-SNJ60B0-320F/port_config.ini @@ -0,0 +1,35 @@ +# name lanes alias index speed +Ethernet0 1,2,3,4,5,6,7,8 Ethernet1/0/1 0 400000 +Ethernet8 9,10,11,12,13,14,15,16 Ethernet1/0/9 1 400000 +Ethernet16 17,18,19,20,21,22,23,24 Ethernet1/0/17 2 400000 +Ethernet24 25,26,27,28,29,30,31,32 Ethernet1/0/25 3 400000 +Ethernet32 33,34,35,36,37,38,39,40 Ethernet1/0/33 4 400000 +Ethernet40 41,42,43,44,45,46,47,48 Ethernet1/0/41 5 400000 +Ethernet48 49,50,51,52,53,54,55,56 Ethernet1/0/48 6 400000 +Ethernet56 57,58,59,60,61,62,63,64 Ethernet1/0/57 7 400000 +Ethernet64 65,66,67,68,69,70,71,72 Ethernet1/0/65 8 400000 +Ethernet72 73,74,75,76,77,78,79,80 Ethernet1/0/73 9 400000 +Ethernet80 81,82,83,84,85,86,87,88 Ethernet1/0/81 10 400000 +Ethernet88 89,90,91,92,93,94,95,96 Ethernet1/0/89 11 400000 +Ethernet96 97,98,99,100,101,102,103,104 Ethernet1/0/97 12 400000 +Ethernet104 105,106,107,108,109,110,111,112 Ethernet1/0/105 13 400000 +Ethernet112 113,114,115,116,117,118,119,120 Ethernet1/0/113 14 400000 +Ethernet120 121,122,123,124,125,126,127,128 Ethernet1/0/121 15 400000 +Ethernet128 129,130,131,132,133,134,135,136 Ethernet1/0/129 16 400000 +Ethernet136 137,138,139,140,141,142,143,144 Ethernet1/0/137 17 400000 +Ethernet144 145,146,147,148,149,150,151,152 Ethernet1/0/145 18 400000 +Ethernet152 153,154,155,156,157,158,159,160 Ethernet1/0/153 19 400000 +Ethernet160 161,162,163,164,165,166,167,168 Ethernet1/0/161 20 400000 +Ethernet168 169,170,171,172,173,174,175,176 Ethernet1/0/169 21 400000 +Ethernet176 177,178,179,180,181,182,183,184 Ethernet1/0/177 22 400000 +Ethernet184 185,186,187,188,189,190,191,192 Ethernet1/0/185 23 400000 +Ethernet192 193,194,195,196,197,198,199,200 Ethernet1/0/193 24 400000 +Ethernet200 201,202,203,204,205,206,207,208 Ethernet1/0/201 25 400000 +Ethernet208 209,210,211,212,213,214,215,216 Ethernet1/0/209 26 400000 +Ethernet216 217,218,219,220,221,222,223,224 Ethernet1/0/217 27 400000 +Ethernet224 225,226,227,228,229,230,231,232 Ethernet1/0/225 28 400000 +Ethernet232 233,234,235,236,237,238,239,240 Ethernet1/0/233 29 400000 +Ethernet240 241,242,243,244,245,246,247,248 Ethernet1/0/241 30 400000 +Ethernet248 249,250,251,252,253,254,255,256 Ethernet1/0/249 31 400000 +Ethernet256 257 Ethernet1/0/257 32 10000 +Ethernet257 258 Ethernet1/0/258 33 10000 diff --git a/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/Alphanetworks-SNJ60B0-320F/qos.json.j2 b/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/Alphanetworks-SNJ60B0-320F/qos.json.j2 new file mode 100755 index 0000000000..5838547e07 --- /dev/null +++ b/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/Alphanetworks-SNJ60B0-320F/qos.json.j2 @@ -0,0 +1,228 @@ +{%- set PORT_ALL = [] %} +{%- for port in PORT %} + {%- if PORT_ALL.append(port) %}{% endif %} +{%- endfor %} +{%- if PORT_ALL | sort_by_port_index %}{% endif %} + +{%- set port_names_list_all = [] %} +{%- for port in PORT_ALL %} + {%- if port_names_list_all.append(port) %}{% endif %} +{%- endfor %} +{%- set port_names_all = port_names_list_all | join(',') -%} + + +{%- set PORT_ACTIVE = [] %} +{%- if DEVICE_NEIGHBOR is not defined %} + {%- set PORT_ACTIVE = PORT_ALL %} +{%- else %} + {%- for port in DEVICE_NEIGHBOR.keys() %} + {%- if PORT_ACTIVE.append(port) %}{%- endif %} + {%- endfor %} +{%- endif %} +{%- if PORT_ACTIVE | sort_by_port_index %}{% endif %} + +{%- set port_names_list_active = [] %} +{%- for port in PORT_ACTIVE %} + {%- if port_names_list_active.append(port) %}{%- endif %} +{%- endfor %} +{%- set port_names_active = port_names_list_active | join(',') -%} + + +{%- set pfc_to_pg_map_supported_asics = ['mellanox', 'barefoot', 'marvell'] -%} + + +{ +{% if generate_tc_to_pg_map is defined %} + {{- generate_tc_to_pg_map() }} +{% else %} + "TC_TO_PRIORITY_GROUP_MAP": { + "DEFAULT": { + "0": "0", + "1": "0", + "2": "0", + "3": "3", + "4": "4", + "5": "0", + "6": "0", + "7": "7" + } + }, +{% endif %} + "MAP_PFC_PRIORITY_TO_QUEUE": { + "DEFAULT": { + "0": "0", + "1": "1", + "2": "2", + "3": "3", + "4": "4", + "5": "5", + "6": "6", + "7": "7" + } + }, + "TC_TO_QUEUE_MAP": { + "DEFAULT": { + "0": "0", + "1": "1", + "2": "2", + "3": "3", + "4": "4", + "5": "5", + "6": "6", + "7": "7" + } + }, + "DSCP_TO_TC_MAP": { + "DEFAULT": { + "0" : "0", + "1" : "0", + "2" : "0", + "3" : "0", + "4" : "0", + "5" : "0", + "6" : "0", + "7" : "0", + "8" : "0", + "9" : "0", + "10": "0", + "11": "0", + "12": "0", + "13": "0", + "14": "0", + "15": "0", + "16": "0", + "17": "0", + "18": "0", + "19": "0", + "20": "0", + "21": "0", + "22": "0", + "23": "0", + "24": "0", + "25": "0", + "26": "0", + "27": "0", + "28": "0", + "29": "0", + "30": "0", + "31": "0", + "32": "0", + "33": "0", + "34": "0", + "35": "0", + "36": "0", + "37": "0", + "38": "0", + "39": "0", + "40": "0", + "41": "0", + "42": "0", + "43": "0", + "44": "0", + "45": "0", + "46": "0", + "47": "0", + "48": "0", + "49": "0", + "50": "0", + "51": "0", + "52": "0", + "53": "0", + "54": "0", + "55": "0", + "56": "0", + "57": "0", + "58": "0", + "59": "0", + "60": "0", + "61": "0", + "62": "0", + "63": "0" + } + }, + "SCHEDULER": { + "scheduler.0": { + "type" : "DWRR", + "weight": "1" + }, + "scheduler.1": { + "type" : "DWRR", + "weight": "2" + }, + "scheduler.2": { + "type" : "DWRR", + "weight": "3" + }, + "scheduler.3": { + "type" : "DWRR", + "weight": "4" + }, + "scheduler.4": { + "type" : "DWRR", + "weight": "5" + }, + "scheduler.5": { + "type" : "DWRR", + "weight": "10" + }, + "scheduler.6": { + "type" : "DWRR", + "weight": "25" + }, + "scheduler.7": { + "type" : "DWRR", + "weight": "50" + } + }, + "PORT_QOS_MAP": { + "{{ port_names_active }}": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|DEFAULT]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|DEFAULT]", + "pfc_enable" : "3,4", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|DEFAULT]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|DEFAULT]" + } + }, + "QUEUE": { +{% for port in PORT_ACTIVE %} + "{{ port }}|0": { + "scheduler" : "[SCHEDULER|scheduler.0]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|1": { + "scheduler" : "[SCHEDULER|scheduler.1]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|2": { + "scheduler": "[SCHEDULER|scheduler.2]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|3": { + "scheduler": "[SCHEDULER|scheduler.3]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|4": { + "scheduler": "[SCHEDULER|scheduler.4]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|5": { + "scheduler": "[SCHEDULER|scheduler.5]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|6": { + "scheduler": "[SCHEDULER|scheduler.6]" + }, +{% endfor %} +{% for port in PORT_ACTIVE %} + "{{ port }}|7": { + "scheduler": "[SCHEDULER|scheduler.7]" + }{% if not loop.last %},{% endif %} +{% endfor %} + } +} diff --git a/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/Alphanetworks-SNJ60B0-320F/sai.profile b/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/Alphanetworks-SNJ60B0-320F/sai.profile new file mode 100755 index 0000000000..9b506d7183 --- /dev/null +++ b/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/Alphanetworks-SNJ60B0-320F/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/th3-snj60b0-32x400G.config.bcm diff --git a/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/Alphanetworks-SNJ60B0-320F/th3-snj60b0-32x400G.config.bcm b/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/Alphanetworks-SNJ60B0-320F/th3-snj60b0-32x400G.config.bcm new file mode 100755 index 0000000000..f3bf629f06 --- /dev/null +++ b/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/Alphanetworks-SNJ60B0-320F/th3-snj60b0-32x400G.config.bcm @@ -0,0 +1,298 @@ +# This property file is for JUNGFRAU 1x400Gx32 mode only. +# JUNGFRAU uses Tomahawk3 BCM56980 as its mac. Besides, it is phyless. + +os=linux +led_fw_path="/usr/share/sonic/platform/" +bcm_stat_interval.0=1000000 +bcm_linkscan_interval.0=250000 + +mdio_output_delay.0=0xf +mem_cache_enable=0 + +parity_enable=0 +core_clock_frequency=1325 + +dpr_clock_frequency=1000 + +# Blackhawk Core - 32 front ports +# BlackhawkCore[0 - 3] must map to device port[1-18], PIPE-0. +portmap_1=1:400 +portmap_5=9:400 +portmap_9=17:400 +portmap_13=25:400 + +# BlackhawkCore[4 - 7] must map to device port[20-37], PIPE-1. +portmap_20=33:400 +portmap_24=41:400 +portmap_28=49:400 +portmap_32=57:400 + +# BlackhawkCore[8 - 11] must map to logical port[40-57], PIPE-2. +portmap_40=65:400 +portmap_44=73:400 +portmap_48=81:400 +portmap_52=89:400 + +# BlackhawkCore[12 - 15] must map to logical port[60-77], PIPE-3. +portmap_60=97:400 +portmap_64=105:400 +portmap_68=113:400 +portmap_72=121:400 + +# BlackhawkCore[16 - 19] must map to logical port[80-97], PIPE-4. +portmap_80=129:400 +portmap_84=137:400 +portmap_88=145:400 +portmap_92=153:400 + +# BlackhawkCore[20 - 23] must map to logical port[100-117], PIPE-5. +portmap_100=161:400 +portmap_104=169:400 +portmap_108=177:400 +portmap_112=185:400 + +# BlackhawkCore[24 - 27] must map to logical port[120-137], PIPE-6. +portmap_120=193:400 +portmap_124=201:400 +portmap_128=209:400 +portmap_132=217:400 + +# BlackhawkCore[28 - 31] must map to logical port[140-157], PIPE-7. +portmap_140=225:400 +portmap_144=233:400 +portmap_148=241:400 +portmap_152=249:400 + +# Merlin Core - 2 management ports +portmap_38=257:10 +portmap_118=258:10 + +# Configure all front port as XE and CD ports. +pbmp_xport_xe=0x0FFFF0FFFF4FFFF0FFFF0FFFF0FFFF4FFFF1FFFE +pbmp_oversubscribe=0x0FFFF0FFFF4FFFF0FFFF0FFFF0FFFF4FFFF1FFFE + +# lane map and polarity +# BlackhawkCore0 +phy_chain_rx_lane_map_physical{1.0}=0x42735061 +serdes_core_rx_polarity_flip_physical{1}=0xe6 +phy_chain_tx_lane_map_physical{1.0}=0x71056243 +serdes_core_tx_polarity_flip_physical{1}=0xa1 + +# BlackhawkCore1 +phy_chain_rx_lane_map_physical{9.0}=0x27150634 +serdes_core_rx_polarity_flip_physical{9}=0xd8 +phy_chain_tx_lane_map_physical{9.0}=0x63520714 +serdes_core_tx_polarity_flip_physical{9}=0x2c + +# BlackhawkCore2 +phy_chain_rx_lane_map_physical{17.0}=0x43025176 +serdes_core_rx_polarity_flip_physical{17}=0xcb +phy_chain_tx_lane_map_physical{17.0}=0x21034765 +serdes_core_tx_polarity_flip_physical{17}=0x4f + +# BlackhawkCore3 +phy_chain_rx_lane_map_physical{25.0}=0x67352014 +serdes_core_rx_polarity_flip_physical{25}=0x72 +phy_chain_tx_lane_map_physical{25.0}=0x62730415 +serdes_core_tx_polarity_flip_physical{25}=0x69 + +# BlackhawkCore4 +phy_chain_rx_lane_map_physical{33.0}=0x13026754 +serdes_core_rx_polarity_flip_physical{33}=0xc3 +phy_chain_tx_lane_map_physical{33.0}=0x35274061 +serdes_core_tx_polarity_flip_physical{33}=0x8e + +# BlackhawkCore5 +phy_chain_rx_lane_map_physical{41.0}=0x35270146 +serdes_core_rx_polarity_flip_physical{41}=0x78 +phy_chain_tx_lane_map_physical{41.0}=0x73526014 +serdes_core_tx_polarity_flip_physical{41}=0xa4 + +# BlackhawkCore6 +phy_chain_rx_lane_map_physical{49.0}=0x13025647 +serdes_core_rx_polarity_flip_physical{49}=0xcc +phy_chain_tx_lane_map_physical{49.0}=0x37054162 +serdes_core_tx_polarity_flip_physical{49}=0x9b + +# BlackhawkCore7 +phy_chain_rx_lane_map_physical{57.0}=0x35270416 +serdes_core_rx_polarity_flip_physical{57}=0x78 +phy_chain_tx_lane_map_physical{57.0}=0x63720415 +serdes_core_tx_polarity_flip_physical{57}=0xb9 + +# BlackhawkCore8 +phy_chain_rx_lane_map_physical{65.0}=0x13024756 +serdes_core_rx_polarity_flip_physical{65}=0xc3 +phy_chain_tx_lane_map_physical{65.0}=0x37054162 +serdes_core_tx_polarity_flip_physical{65}=0xab + +# BlackhawkCore9 +phy_chain_rx_lane_map_physical{73.0}=0x35270146 +serdes_core_rx_polarity_flip_physical{73}=0x78 +phy_chain_tx_lane_map_physical{73.0}=0x63720514 +serdes_core_tx_polarity_flip_physical{73}=0x3c + +# BlackhawkCore10 +phy_chain_rx_lane_map_physical{81.0}=0x13024756 +serdes_core_rx_polarity_flip_physical{81}=0xc3 +phy_chain_tx_lane_map_physical{81.0}=0x35204761 +serdes_core_tx_polarity_flip_physical{81}=0x9e + +# BlackhawkCore11 +phy_chain_rx_lane_map_physical{89.0}=0x35270416 +serdes_core_rx_polarity_flip_physical{89}=0x78 +phy_chain_tx_lane_map_physical{89.0}=0x73620514 +serdes_core_tx_polarity_flip_physical{89}=0x8c + +# BlackhawkCore12 +phy_chain_rx_lane_map_physical{97.0}=0x13024756 +serdes_core_rx_polarity_flip_physical{97}=0xc3 +phy_chain_tx_lane_map_physical{97.0}=0x37154062 +serdes_core_tx_polarity_flip_physical{97}=0xaf + +# BlackhawkCore13 +phy_chain_rx_lane_map_physical{105.0}=0x45671320 +serdes_core_rx_polarity_flip_physical{105}=0x53 +phy_chain_tx_lane_map_physical{105.0}=0x62730415 +serdes_core_tx_polarity_flip_physical{105}=0x69 + +# BlackhawkCore14 +phy_chain_rx_lane_map_physical{113.0}=0x13026754 +serdes_core_rx_polarity_flip_physical{113}=0xc3 +phy_chain_tx_lane_map_physical{113.0}=0x17254063 +serdes_core_tx_polarity_flip_physical{113}=0x8e + +# BlackhawkCore15 +phy_chain_rx_lane_map_physical{121.0}=0x65471230 +serdes_core_rx_polarity_flip_physical{121}=0xaa +phy_chain_tx_lane_map_physical{121.0}=0x27351406 +serdes_core_tx_polarity_flip_physical{121}=0x3d + +# BlackhawkCore16 +phy_chain_rx_lane_map_physical{129.0}=0x62735140 +serdes_core_rx_polarity_flip_physical{129}=0x63 +phy_chain_tx_lane_map_physical{129.0}=0x52736140 +serdes_core_tx_polarity_flip_physical{129}=0xf4 + +# BlackhawkCore17 +phy_chain_rx_lane_map_physical{137.0}=0x35270416 +serdes_core_rx_polarity_flip_physical{137}=0x78 +phy_chain_tx_lane_map_physical{137.0}=0x52731604 +serdes_core_tx_polarity_flip_physical{137}=0xe2 + +# BlackhawkCore18 +phy_chain_rx_lane_map_physical{145.0}=0x02135746 +serdes_core_rx_polarity_flip_physical{145}=0x39 +phy_chain_tx_lane_map_physical{145.0}=0x15274063 +serdes_core_tx_polarity_flip_physical{145}=0x8e + +# BlackhawkCore19 +phy_chain_rx_lane_map_physical{153.0}=0x05471263 +serdes_core_rx_polarity_flip_physical{153}=0x81 +phy_chain_tx_lane_map_physical{153.0}=0x43621705 +serdes_core_tx_polarity_flip_physical{153}=0x9f + +# BlackhawkCore20 +phy_chain_rx_lane_map_physical{161.0}=0x13620475 +serdes_core_rx_polarity_flip_physical{161}=0x66 +phy_chain_tx_lane_map_physical{161.0}=0x35274061 +serdes_core_tx_polarity_flip_physical{161}=0x2f + +# BlackhawkCore21 +phy_chain_rx_lane_map_physical{169.0}=0x15074263 +serdes_core_rx_polarity_flip_physical{169}=0x71 +phy_chain_tx_lane_map_physical{169.0}=0x52731604 +serdes_core_tx_polarity_flip_physical{169}=0x62 + +# BlackhawkCore22 +phy_chain_rx_lane_map_physical{177.0}=0x13620475 +serdes_core_rx_polarity_flip_physical{177}=0xee +phy_chain_tx_lane_map_physical{177.0}=0x37254061 +serdes_core_tx_polarity_flip_physical{177}=0x8e + +# BlackhawkCore23 +phy_chain_rx_lane_map_physical{185.0}=0x15074263 +serdes_core_rx_polarity_flip_physical{185}=0x71 +phy_chain_tx_lane_map_physical{185.0}=0x52730614 +serdes_core_tx_polarity_flip_physical{185}=0x68 + +# BlackhawkCore24 +phy_chain_rx_lane_map_physical{193.0}=0x13620475 +serdes_core_rx_polarity_flip_physical{193}=0xee +phy_chain_tx_lane_map_physical{193.0}=0x37254061 +serdes_core_tx_polarity_flip_physical{193}=0x8e + +# BlackhawkCore25 +phy_chain_rx_lane_map_physical{201.0}=0x15074263 +serdes_core_rx_polarity_flip_physical{201}=0x71 +phy_chain_tx_lane_map_physical{201.0}=0x53720614 +serdes_core_tx_polarity_flip_physical{201}=0x38 + +# BlackhawkCore26 +phy_chain_rx_lane_map_physical{209.0}=0x13620745 +serdes_core_rx_polarity_flip_physical{209}=0xe8 +phy_chain_tx_lane_map_physical{209.0}=0x30156742 +serdes_core_tx_polarity_flip_physical{209}=0xa7 + +# BlackhawkCore27 +phy_chain_rx_lane_map_physical{217.0}=0x15072364 +serdes_core_rx_polarity_flip_physical{217}=0x79 +phy_chain_tx_lane_map_physical{217.0}=0x52730614 +serdes_core_tx_polarity_flip_physical{217}=0x68 + +# BlackhawkCore28 +phy_chain_rx_lane_map_physical{225.0}=0x03126574 +serdes_core_rx_polarity_flip_physical{225}=0x6c +phy_chain_tx_lane_map_physical{225.0}=0x35274061 +serdes_core_tx_polarity_flip_physical{225}=0x8e + +# BlackhawkCore29 +phy_chain_rx_lane_map_physical{233.0}=0x35472160 +serdes_core_rx_polarity_flip_physical{233}=0x26 +phy_chain_tx_lane_map_physical{233.0}=0x52630714 +serdes_core_tx_polarity_flip_physical{233}=0xcc + +# BlackhawkCore30 +phy_chain_rx_lane_map_physical{241.0}=0x03126475 +serdes_core_rx_polarity_flip_physical{241}=0x66 +phy_chain_tx_lane_map_physical{241.0}=0x37254061 +serdes_core_tx_polarity_flip_physical{241}=0x8e + +# BlackhawkCore31 +phy_chain_rx_lane_map_physical{249.0}=0x45673120 +serdes_core_rx_polarity_flip_physical{249}=0xac +phy_chain_tx_lane_map_physical{249.0}=0x37250416 +serdes_core_tx_polarity_flip_physical{249}=0x87 + +serdes_tx_taps_cd0=pam4:-24:144:0:0:0:0 +serdes_tx_taps_cd1=pam4:-24:144:0:0:0:0 +serdes_tx_taps_cd2=pam4:-24:144:0:0:0:0 +serdes_tx_taps_cd3=pam4:-24:144:0:0:0:0 +serdes_tx_taps_cd4=pam4:-24:144:0:0:0:0 +serdes_tx_taps_cd5=pam4:-24:144:0:0:0:0 +serdes_tx_taps_cd6=pam4:-24:144:0:0:0:0 +serdes_tx_taps_cd7=pam4:-24:144:0:0:0:0 +serdes_tx_taps_cd8=pam4:-20:148:0:0:0:0 +serdes_tx_taps_cd9=pam4:-20:148:0:0:0:0 +serdes_tx_taps_cd10=pam4:-20:148:0:0:0:0 +serdes_tx_taps_cd11=pam4:-24:144:0:0:0:0 +serdes_tx_taps_cd12=pam4:-24:144:0:0:0:0 +serdes_tx_taps_cd13=pam4:-20:148:0:0:0:0 +serdes_tx_taps_cd14=pam4:-24:144:0:0:0:0 +serdes_tx_taps_cd15=pam4:-20:148:0:0:0:0 +serdes_tx_taps_cd16=pam4:-24:144:0:0:0:0 +serdes_tx_taps_cd17=pam4:-20:148:0:0:0:0 +serdes_tx_taps_cd18=pam4:-20:148:0:0:0:0 +serdes_tx_taps_cd19=pam4:-20:148:0:0:0:0 +serdes_tx_taps_cd20=pam4:-24:144:0:0:0:0 +serdes_tx_taps_cd21=pam4:-20:148:0:0:0:0 +serdes_tx_taps_cd22=pam4:-20:148:0:0:0:0 +serdes_tx_taps_cd23=pam4:-24:144:0:0:0:0 +serdes_tx_taps_cd24=pam4:-24:144:0:0:0:0 +serdes_tx_taps_cd25=pam4:-24:144:0:0:0:0 +serdes_tx_taps_cd26=pam4:-20:148:0:0:0:0 +serdes_tx_taps_cd27=pam4:-24:144:0:0:0:0 +serdes_tx_taps_cd28=pam4:-24:144:0:0:0:0 +serdes_tx_taps_cd29=pam4:-24:144:0:0:0:0 +serdes_tx_taps_cd30=pam4:-20:148:0:0:0:0 +serdes_tx_taps_cd31=pam4:-24:144:0:0:0:0 diff --git a/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/custom_led.bin b/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/custom_led.bin new file mode 100755 index 0000000000000000000000000000000000000000..fdbf3aa30a80aa348fbd08f82b55c5d2b1fa1bd9 GIT binary patch literal 996 zcmaiyUr1A77{;Ho9i2AqXk`#tdA?JKf3UU6atiIN@xe?GCsJt_o^8VMqKobdf^LMPjP{+Akh1t6EOHXl{_9L=T*Yg*EXV?t9$Tzq2&2HsZltWm42z_YPrqN0kS0 zDQPqQY?gRlQeruV;Jh7)cz(>4B)76*n>8Nds3wwm^?=`UOsp%dm`S*qBzyHyzv%3& zTuzKN7CB2wFYk|*Um>H97rSrp$~B`kDXbVf+Uv=+gpHh44Rx?j?EzKV@ZBRd< z-Ao>N9#D&!E}#~Wk7DeCOwaic>Y&1h7Mz8KZd|}6^kM+FFo;n+#3MYz6sD2DERy(& L@AwHpunNBcX5ctY literal 0 HcmV?d00001 diff --git a/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/default_sku b/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/default_sku new file mode 100755 index 0000000000..073744ed33 --- /dev/null +++ b/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/default_sku @@ -0,0 +1 @@ +Alphanetworks-SNJ60B0-320F t1 diff --git a/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/fancontrol b/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/fancontrol new file mode 100755 index 0000000000..cf46c9159e --- /dev/null +++ b/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/fancontrol @@ -0,0 +1,9 @@ +INTERVAL=10 +FCTEMPS=/sys/bus/i2c/devices/0-005e/fan_pwm=/sys/bus/i2c/devices/3-004d/hwmon/hwmon2/temp1_input +FCFANS=/sys/bus/i2c/devices/0-005e/fan_pwm=/sys/bus/i2c/devices/0-005e/fan1_input /sys/bus/i2c/devices/0-005e/fan_pwm=/sys/bus/i2c/devices/0-005e/fan2_input /sys/bus/i2c/devices/0-005e/fan_pwm=/sys/bus/i2c/devices/0-005e/fan3_input /sys/bus/i2c/devices/0-005e/fan_pwm=/sys/bus/i2c/devices/0-005e/fan4_input /sys/bus/i2c/devices/0-005e/fan_pwm=/sys/bus/i2c/devices/0-005e/fan5_input /sys/bus/i2c/devices/0-005e/fan_pwm=/sys/bus/i2c/devices/0-005e/fan6_input /sys/bus/i2c/devices/0-005e/fan_pwm=/sys/bus/i2c/devices/0-005e/fan11_input /sys/bus/i2c/devices/0-005e/fan_pwm=/sys/bus/i2c/devices/0-005e/fan12_input /sys/bus/i2c/devices/0-005e/fan_pwm=/sys/bus/i2c/devices/0-005e/fan13_input /sys/bus/i2c/devices/0-005e/fan_pwm=/sys/bus/i2c/devices/0-005e/fan14_input /sys/bus/i2c/devices/0-005e/fan_pwm=/sys/bus/i2c/devices/0-005e/fan15_input /sys/bus/i2c/devices/0-005e/fan_pwm=/sys/bus/i2c/devices/0-005e/fan16_input +MINTEMP=/sys/bus/i2c/devices/0-005e/fan_pwm=50 +MAXTEMP=/sys/bus/i2c/devices/0-005e/fan_pwm=70 +MINSTART=/sys/bus/i2c/devices/0-005e/fan_pwm=100 +MINSTOP=/sys/bus/i2c/devices/0-005e/fan_pwm=100 +MINPWM=/sys/bus/i2c/devices/0-005e/fan_pwm=100 +MAXPWM=/sys/bus/i2c/devices/0-005e/fan_pwm=200 \ No newline at end of file diff --git a/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/installer.conf b/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/installer.conf new file mode 100755 index 0000000000..40074bddd1 --- /dev/null +++ b/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/installer.conf @@ -0,0 +1,4 @@ +CONSOLE_PORT=0x3f8 +CONSOLE_DEV=0 +CONSOLE_SPEED=115200 +ONIE_PLATFORM_EXTRA_CMDLINE_LINUX="modprobe.blacklist=i2c-ismt,i2c_ismt,i2c-i801,i2c_i801" diff --git a/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/led_proc_init.soc b/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/led_proc_init.soc new file mode 100755 index 0000000000..547f4174a2 --- /dev/null +++ b/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/led_proc_init.soc @@ -0,0 +1,11 @@ +# LED microprocessor initialization for alphanetworks snj60b0-320f + +#LED FW is loaded in SAI platform_init.c +#m0 load 0 0x3800 /alpha/bcm/led/jungfrau-320f_traffic_led.bin +led start +led auto on + +# Load SFP Pre-Emphasis static configure +# This is work around for 6-taps mode +rcload /usr/share/sonic/platform/preemphasis-32x400G.soc + diff --git a/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/linkscan_led_fw.bin b/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/linkscan_led_fw.bin new file mode 100755 index 0000000000000000000000000000000000000000..b1e43d4d48d4c037c94200420108b93b57ee375b GIT binary patch literal 5636 zcma)A4|Ee%y8mYKKTX?EiXwDqpf}^Y?q%`xsNeV~b zAJ0q9o%!y)-*@kKzx#c^``v*kKqml%vD}U2n|}9vrE>$){a7MjDLVci2&Gu_z(d<6 z3OjJ@Lgwlp;8q?y{laqomi9onKWy?);b>bld2=Vs^NOs?D?kN!Yovw3kZ6=gL~DhG zwpiCWMuc<(yq8AHWm)uzg8|zaIWi<{57$M&BShkD49=-seo=(x3#0RRVA3R-iYARD zCR#m|^3Y{>r%znvU>Hg<<-t2!dPVFP7DcG=1CiG71LB)Ps}K<>A?S(-FNiP?d=}}n z2=xa7HDe>;A)!Xb5xHn;d-!BHn>ihUCbKjy{xD!Ub0T~?5)Yrkm6+v|_}&)Q%VlH+ zIV~Otd@=@1GzBccp-%?@WROEhtJ%j?3m>~^83ZPFv3l^ci`6mOW9Bsa_{ID8g5oJq z%4fMk25t8k7AD%}Z?6)~td$)IP@@#qwYKKfkaUt}Ud<{hcnzaY(uDLUNK=xRhm=<8 zi#+w%{^w~P57K9fJRa=tWMXUJe znw8X5>-;HuQjhd$71rCQ=_5t@D%as67l5)9i;C{>8!Sm&SDdm#d=Ywx-hN<1y*)m= zL1%q?S3ozGa0~{FVuYv8V($I`HGXx~(WId+7p$V8A;jJ02r&ZZb&T8#KC{%i z(fIbhfL`j~2tG8b}#jToe>2YjJVPr$mOq9v)j~&2>U3dEoUUa zc;r{iPZC2TeNbAxfR1p#cZ57p*UH`Hm_fYrALcfOo_9tZYX$nbUBW5hZc-M8`d#6& zo_E4suGKxu3ElL`1nYu>gMmMdYhHRZcf5mYJS2eEEV(gWUJp`X@Z2V}hSlu;LZk5G zj6M0g_AYT>fF9SQZ`xCax+*%vz0y8_R^hpsj&6(>S~3*-ppI(rG9k|4=yI(J(@nVv zGtqYImtP;Dp@9~-Lmf~D&QL>`n@L!Q*RzgmMXA+ADPS}y@KsJEI(o&Q1j@z?MVb8_ zB?;E?M(;qc##Pb@eD;am#W`$ahWa^lH@9;&)TJGv`t=;^80bCGYbVh*jW^m>(!akw z<_OiT!``bck6vr>`lD^RWJS^Ueo=rpEU1+H#OybbzeYewsexJ#@!}4hEnqz0{-(KH zQIA}zg@E#F>_1BC3F3ulmG{5~^7{H6@aJ_4Bdjav+8%&Wn%NilVq6e?kr;X)Jr2rx zbsT84{pe zDX_H=kBZ00Vze?9x5~TF%9GtYV0_*6MJsPBS{a@@82Ehr0r8Z>7b&ga7llDrRGMO7@P^P=+2-?_inEnnlF#)WoV`)oFh@P(`%UlwDprvvre;h z&^1t+=UHt(fjOLsCiP&Fu5@1Eedr(EQ)u;33NbyJ@{t@y{#tC&Neu46xqLL$>lQ3A zQ2h`2)$B7<8frW{T$2FrjnaiqXtYLK2o*5jLc+dc7K4Dc($Kgwr;a)@xt>HHHl3wYMpJt z#}mNJL7VDuukslMk#+Yl&!F!X3~-C&t2H3~t%8r(@x2z`=0!H7+7a6*avvE0*7Zur z=FLwq;*Dgak_D;`;&GVY-R0T}mE7DA(>+pYYx;5=8V*6L)8Ada2$bs!y)IkxrHNP3 zHh@UErl7}N1|?WvNIB}FAxIw4=H=DExCl-BOZwrC5bNr}nJ!P*F&YkcyfSP8z0^_* zN`8t$)M3btD5?1lD4$Qo!0)9$(ERUW1~q-bP}FpHQB!F6B`8iU8a|w&Ug&iVuCq0N ziB>3ou^(4+Pm#x8N4?-20%d5b{4g-im-=D1^TF-~4|kc*o0>S*bw{Yo`?qoQ-tO&d zf@UZBa6j~Pv#tk=8uoWUqkoB5+_A|5MTTH;_a>K>tqa)}T)ehV=;6hE`UE*1;(yTY z_rv6iwy|`oNCN}boFKIlRTz=fQvlA547la10a0o`G?YecU zWLFJ)?w_JPgPaXd`DIvpa7y5pk;Tty)}B|0VAPsO_0sig%88zUS1&PW$J?i9Jfr+1 zm!cSy(S!1xDa}9IuZ`rvTIbXnzKI}(BTJmaoWHPwA)SZwyk?^471(mrpIcCO?AmO47$e1Bkna8*wErNyKOq z3VN75%B%&Cf9Wo8^M&pc-6BbMUx#tb@gRztd<7@W zfv4&{jz02z)cH*n60PnVe7dn1q@A&rH#hXUc+7sNdg@o-3x1EMo>sG%mw7D{ck!`4 zpjs=b1Z!d|TUjdpfIu;Rp@6%G{x{!iz9}EUji+-G;^-osRUPBJe-y$fzRH~!ax$KLdA%3|9_f^Yj zc=run!_20DrQ;acI^#Ip zM~*w2#P5^MmS?%mRFklM&PtJDhFKGOQVrLH8TcV*J`|!hsM0{KD2U6 z$`rJU(1c^v4Y0gOYd$=kliPGN><#Es$I#cH741gbn_)Z9K)0al)!6}FjR9?T#r9El z%z@`Mpw0dc?;~cksOH_XCNXy3(-1eBqC8(_sG`q5I60>iGaEtUcxX~bM8VPSDfTRz zG=Sl~6787u;++S5bV@tdFiS&ycjUF4UJq5H46g5qNlOsCgMwAE1TA>~u@rO4*09dg zDyUiUGJ`o`>CDyQ~3#lA>rh!y1sUVt9ox+iJ9AS#5%ZYsYh=!?Z&VwVqmDf=5M81@# z{9MgVOIDz)1J9Vlc})(K=W&GoBe!U?EB~oQIliBtmfDF@m@klOe>pKC?>?LX6ggMY z>OkIyI;h#rsOYCd?PCJ|_rs?L)3 zZ8h=0&657C)!QufdYRE?Ilwy{eksr{1)QUXI!H9iEI+emAaH|ZKD&aqJG{~g>?<2J zW8Z9fIdV5jw_*!DT81qZax+;}v`X8wy?kgdJogin3<84EryWUTo76we^=z`h8sES}dx<-59h@S{r{EU-vkTt#JG2cRs@8;oVw&6vZ0 zb}p52ZEFz+wXAyq-ixXb6E%93n#+`^JJgHQl&D_FEGcFduDpiMJo?ruEJI;{M+m?< zoT4GGsz?7#RdWp#h;ON?az<5!hYM=@iz|pMI*eYuG@p;QSs2ja{eWTdSyrSWsb(*z zJM|VDdk5ZDv6d;;0$q@D@vtS@RueQwwP)I75l@R<<}OHA(%fkw+BQqWq({=GbY--y zDwsA}#3v$MmM$t?L32;w*NJkz7xRDEqj6{m5p++EM%zrq*4Te*#rr+paa*R>rX=^b z&uu&@KDBy($FB|hL|EvQZr?)9U%}lT-Ts8>iA!@fyN;4SM2;KW?AG!X+y=7MFpoWM zUBUe!Y5%%zR2 z#e{V6ykpwdP;rRsi9f1ljVkH%3KZfPrHaBTen?o=j`<@MbXvpj2(0VLaC_L`y)>a_ zrwY{kVPU0i84*RymUI7TAHw$wIV}@Bf?t((I^MaP@#ZkE1VogcoB`+}%3`Eo?Bmyq zoQ^2M!gj;ye^mQ!pka4?ruEPNst0i~e^f2~fC0XVlF~1Gf zYhhk>d!?)scLmDEcLfX|+*!jpZWH})m~RD{6K4u^S})VJcFbS?I*NGj)s41He@RkO z#&#ob7mV#yHDl&6Se2%j7UBI&H;%8(p$`Ebq5!mPK81E3fu=kn2wH@pWNM^pE;MO~ jQd+q>XwNAV2ag7t6uxxcCN|IznfOtH}O literal 0 HcmV?d00001 diff --git a/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/media_settings.json b/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/media_settings.json new file mode 100755 index 0000000000..1e3db76e49 --- /dev/null +++ b/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/media_settings.json @@ -0,0 +1,836 @@ +{ + "PORT_MEDIA_SETTINGS": { + "0": { + "Default": { + "preemphasis": { + "lane0": "0x0c8418", + "lane1": "0x0c8418", + "lane2": "0x0c8418", + "lane3": "0x0c8418", + "lane4": "0x0c8418", + "lane5": "0x0c8418", + "lane6": "0x0c8418", + "lane7": "0x0c8418" + } + }, + "QSFP-DD,QSFP28-40GBASE-CR4-1M": { + "preemphasis": { + "lane0": "0x0c8418", + "lane1": "0x0c8418", + "lane2": "0x0c8418", + "lane3": "0x0c8418", + "lane4": "0x0c8418", + "lane5": "0x0c8418", + "lane6": "0x0c8418", + "lane7": "0x0c8418" + } + } + }, + "1": { + "Default": { + "preemphasis": { + "lane0": "0x0c8418", + "lane1": "0x0c8418", + "lane2": "0x0c8418", + "lane3": "0x0c8418", + "lane4": "0x0c8418", + "lane5": "0x0c8418", + "lane6": "0x0c8418", + "lane7": "0x0c8418" + } + }, + "QSFP-DD,QSFP28-40GBASE-CR4-1M": { + "preemphasis": { + "lane0": "0x0c8418", + "lane1": "0x0c8418", + "lane2": "0x0c8418", + "lane3": "0x0c8418", + "lane4": "0x0c8418", + "lane5": "0x0c8418", + "lane6": "0x0c8418", + "lane7": "0x0c8418" + } + } + }, + "2": { + "Default": { + "preemphasis": { + "lane0": "0x0c701c", + "lane1": "0x0c701c", + "lane2": "0x0c701c", + "lane3": "0x0c701c", + "lane4": "0x0c701c", + "lane5": "0x0c701c", + "lane6": "0x0c701c", + "lane7": "0x0c701c" + } + }, + "QSFP-DD,QSFP28-40GBASE-CR4-1M": { + "preemphasis": { + "lane0": "0x0c701c", + "lane1": "0x0c701c", + "lane2": "0x0c701c", + "lane3": "0x0c701c", + "lane4": "0x0c701c", + "lane5": "0x0c701c", + "lane6": "0x0c701c", + "lane7": "0x0c701c" + } + } + }, + "3": { + "Default": { + "preemphasis": { + "lane0": "0x10741c", + "lane1": "0x10741c", + "lane2": "0x10741c", + "lane3": "0x10741c", + "lane4": "0x10741c", + "lane5": "0x10741c", + "lane6": "0x10741c", + "lane7": "0x10741c" + } + }, + "QSFP-DD,QSFP28-40GBASE-CR4-1M": { + "preemphasis": { + "lane0": "0x10741c", + "lane1": "0x10741c", + "lane2": "0x10741c", + "lane3": "0x10741c", + "lane4": "0x10741c", + "lane5": "0x10741c", + "lane6": "0x10741c", + "lane7": "0x10741c" + } + } + }, + "4": { + "Default": { + "preemphasis": { + "lane0": "0x0c781c", + "lane1": "0x0c781c", + "lane2": "0x0c781c", + "lane3": "0x0c781c", + "lane4": "0x0c781c", + "lane5": "0x0c781c", + "lane6": "0x0c781c", + "lane7": "0x0c781c" + } + }, + "QSFP-DD,QSFP28-40GBASE-CR4-1M": { + "preemphasis": { + "lane0": "0x0c781c", + "lane1": "0x0c781c", + "lane2": "0x0c781c", + "lane3": "0x0c781c", + "lane4": "0x0c781c", + "lane5": "0x0c781c", + "lane6": "0x0c781c", + "lane7": "0x0c781c" + } + } + }, + "5": { + "Default": { + "preemphasis": { + "lane0": "0x0c7c18", + "lane1": "0x0c7c18", + "lane2": "0x0c7c18", + "lane3": "0x0c7c18", + "lane4": "0x0c7c18", + "lane5": "0x0c7c18", + "lane6": "0x0c7c18", + "lane7": "0x0c7c18" + } + }, + "QSFP-DD,QSFP28-40GBASE-CR4-1M": { + "preemphasis": { + "lane0": "0x0c7c18", + "lane1": "0x0c7c18", + "lane2": "0x0c7c18", + "lane3": "0x0c7c18", + "lane4": "0x0c7c18", + "lane5": "0x0c7c18", + "lane6": "0x0c7c18", + "lane7": "0x0c7c18" + } + } + }, + "6": { + "Default": { + "preemphasis": { + "lane0": "0x008020", + "lane1": "0x008020", + "lane2": "0x008020", + "lane3": "0x008020", + "lane4": "0x008020", + "lane5": "0x008020", + "lane6": "0x008020", + "lane7": "0x008020" + } + }, + "QSFP-DD,QSFP28-40GBASE-CR4-1M": { + "preemphasis": { + "lane0": "0x008020", + "lane1": "0x008020", + "lane2": "0x008020", + "lane3": "0x008020", + "lane4": "0x008020", + "lane5": "0x008020", + "lane6": "0x008020", + "lane7": "0x008020" + } + } + }, + "7": { + "Default": { + "preemphasis": { + "lane0": "0x00881c", + "lane1": "0x00881c", + "lane2": "0x00881c", + "lane3": "0x00881c", + "lane4": "0x00881c", + "lane5": "0x00881c", + "lane6": "0x00881c", + "lane7": "0x00881c" + } + }, + "QSFP-DD,QSFP28-40GBASE-CR4-1M": { + "preemphasis": { + "lane0": "0x00881c", + "lane1": "0x00881c", + "lane2": "0x00881c", + "lane3": "0x00881c", + "lane4": "0x00881c", + "lane5": "0x00881c", + "lane6": "0x00881c", + "lane7": "0x00881c" + } + } + }, + "8": { + "Default": { + "preemphasis": { + "lane0": "0x00881c", + "lane1": "0x00881c", + "lane2": "0x00881c", + "lane3": "0x00881c", + "lane4": "0x00881c", + "lane5": "0x00881c", + "lane6": "0x00881c", + "lane7": "0x00881c" + } + }, + "QSFP-DD,QSFP28-40GBASE-CR4-1M": { + "preemphasis": { + "lane0": "0x00881c", + "lane1": "0x00881c", + "lane2": "0x00881c", + "lane3": "0x00881c", + "lane4": "0x00881c", + "lane5": "0x00881c", + "lane6": "0x00881c", + "lane7": "0x00881c" + } + } + }, + "9": { + "Default": { + "preemphasis": { + "lane0": "0x009018", + "lane1": "0x009018", + "lane2": "0x009018", + "lane3": "0x009018", + "lane4": "0x009018", + "lane5": "0x009018", + "lane6": "0x009018", + "lane7": "0x009018" + } + }, + "QSFP-DD,QSFP28-40GBASE-CR4-1M": { + "preemphasis": { + "lane0": "0x009018", + "lane1": "0x009018", + "lane2": "0x009018", + "lane3": "0x009018", + "lane4": "0x009018", + "lane5": "0x009018", + "lane6": "0x009018", + "lane7": "0x009018" + } + } + }, + "10": { + "Default": { + "preemphasis": { + "lane0": "0x00841c", + "lane1": "0x00841c", + "lane2": "0x00841c", + "lane3": "0x00841c", + "lane4": "0x00841c", + "lane5": "0x00841c", + "lane6": "0x00841c", + "lane7": "0x00841c" + } + }, + "QSFP-DD,QSFP28-40GBASE-CR4-1M": { + "preemphasis": { + "lane0": "0x00841c", + "lane1": "0x00841c", + "lane2": "0x00841c", + "lane3": "0x00841c", + "lane4": "0x00841c", + "lane5": "0x00841c", + "lane6": "0x00841c", + "lane7": "0x00841c" + } + } + }, + "11": { + "Default": { + "preemphasis": { + "lane0": "0x009018", + "lane1": "0x009018", + "lane2": "0x009018", + "lane3": "0x009018", + "lane4": "0x009018", + "lane5": "0x009018", + "lane6": "0x009018", + "lane7": "0x009018" + } + }, + "QSFP-DD,QSFP28-40GBASE-CR4-1M": { + "preemphasis": { + "lane0": "0x009018", + "lane1": "0x009018", + "lane2": "0x009018", + "lane3": "0x009018", + "lane4": "0x009018", + "lane5": "0x009018", + "lane6": "0x009018", + "lane7": "0x009018" + } + } + }, + "12": { + "Default": { + "preemphasis": { + "lane0": "0x008c1c", + "lane1": "0x008c1c", + "lane2": "0x008c1c", + "lane3": "0x008c1c", + "lane4": "0x008c1c", + "lane5": "0x008c1c", + "lane6": "0x008c1c", + "lane7": "0x008c1c" + } + }, + "QSFP-DD,QSFP28-40GBASE-CR4-1M": { + "preemphasis": { + "lane0": "0x008c1c", + "lane1": "0x008c1c", + "lane2": "0x008c1c", + "lane3": "0x008c1c", + "lane4": "0x008c1c", + "lane5": "0x008c1c", + "lane6": "0x008c1c", + "lane7": "0x008c1c" + } + } + }, + "13": { + "Default": { + "preemphasis": { + "lane0": "0x009018", + "lane1": "0x009018", + "lane2": "0x009018", + "lane3": "0x009018", + "lane4": "0x009018", + "lane5": "0x009018", + "lane6": "0x009018", + "lane7": "0x009018" + } + }, + "QSFP-DD,QSFP28-40GBASE-CR4-1M": { + "preemphasis": { + "lane0": "0x009018", + "lane1": "0x009018", + "lane2": "0x009018", + "lane3": "0x009018", + "lane4": "0x009018", + "lane5": "0x009018", + "lane6": "0x009018", + "lane7": "0x009018" + } + } + }, + "14": { + "Default": { + "preemphasis": { + "lane0": "0x0c8418", + "lane1": "0x0c8418", + "lane2": "0x0c8418", + "lane3": "0x0c8418", + "lane4": "0x0c8418", + "lane5": "0x0c8418", + "lane6": "0x0c8418", + "lane7": "0x0c8418" + } + }, + "QSFP-DD,QSFP28-40GBASE-CR4-1M": { + "preemphasis": { + "lane0": "0x0c8418", + "lane1": "0x0c8418", + "lane2": "0x0c8418", + "lane3": "0x0c8418", + "lane4": "0x0c8418", + "lane5": "0x0c8418", + "lane6": "0x0c8418", + "lane7": "0x0c8418" + } + } + }, + "15": { + "Default": { + "preemphasis": { + "lane0": "0x0c8418", + "lane1": "0x0c8418", + "lane2": "0x0c8418", + "lane3": "0x0c8418", + "lane4": "0x0c8418", + "lane5": "0x0c8418", + "lane6": "0x0c8418", + "lane7": "0x0c8418" + } + }, + "QSFP-DD,QSFP28-40GBASE-CR4-1M": { + "preemphasis": { + "lane0": "0x0c8418", + "lane1": "0x0c8418", + "lane2": "0x0c8418", + "lane3": "0x0c8418", + "lane4": "0x0c8418", + "lane5": "0x0c8418", + "lane6": "0x0c8418", + "lane7": "0x0c8418" + } + } + }, + "16": { + "Default": { + "preemphasis": { + "lane0": "0x009018", + "lane1": "0x009018", + "lane2": "0x009018", + "lane3": "0x009018", + "lane4": "0x009018", + "lane5": "0x009018", + "lane6": "0x009018", + "lane7": "0x009018" + } + }, + "QSFP-DD,QSFP28-40GBASE-CR4-1M": { + "preemphasis": { + "lane0": "0x009018", + "lane1": "0x009018", + "lane2": "0x009018", + "lane3": "0x009018", + "lane4": "0x009018", + "lane5": "0x009018", + "lane6": "0x009018", + "lane7": "0x009018" + } + } + }, + "17": { + "Default": { + "preemphasis": { + "lane0": "0x009018", + "lane1": "0x009018", + "lane2": "0x009018", + "lane3": "0x009018", + "lane4": "0x009018", + "lane5": "0x009018", + "lane6": "0x009018", + "lane7": "0x009018" + } + }, + "QSFP-DD,QSFP28-40GBASE-CR4-1M": { + "preemphasis": { + "lane0": "0x009018", + "lane1": "0x009018", + "lane2": "0x009018", + "lane3": "0x009018", + "lane4": "0x009018", + "lane5": "0x009018", + "lane6": "0x009018", + "lane7": "0x009018" + } + } + }, + "18": { + "Default": { + "preemphasis": { + "lane0": "0x009018", + "lane1": "0x009018", + "lane2": "0x009018", + "lane3": "0x009018", + "lane4": "0x009018", + "lane5": "0x009018", + "lane6": "0x009018", + "lane7": "0x009018" + } + }, + "QSFP-DD,QSFP28-40GBASE-CR4-1M": { + "preemphasis": { + "lane0": "0x009018", + "lane1": "0x009018", + "lane2": "0x009018", + "lane3": "0x009018", + "lane4": "0x009018", + "lane5": "0x009018", + "lane6": "0x009018", + "lane7": "0x009018" + } + } + }, + "19": { + "Default": { + "preemphasis": { + "lane0": "0x009018", + "lane1": "0x009018", + "lane2": "0x009018", + "lane3": "0x009018", + "lane4": "0x009018", + "lane5": "0x009018", + "lane6": "0x009018", + "lane7": "0x009018" + } + }, + "QSFP-DD,QSFP28-40GBASE-CR4-1M": { + "preemphasis": { + "lane0": "0x009018", + "lane1": "0x009018", + "lane2": "0x009018", + "lane3": "0x009018", + "lane4": "0x009018", + "lane5": "0x009018", + "lane6": "0x009018", + "lane7": "0x009018" + } + } + }, + "20": { + "Default": { + "preemphasis": { + "lane0": "0x008c1c", + "lane1": "0x008c1c", + "lane2": "0x008c1c", + "lane3": "0x008c1c", + "lane4": "0x008c1c", + "lane5": "0x008c1c", + "lane6": "0x008c1c", + "lane7": "0x008c1c" + } + }, + "QSFP-DD,QSFP28-40GBASE-CR4-1M": { + "preemphasis": { + "lane0": "0x008c1c", + "lane1": "0x008c1c", + "lane2": "0x008c1c", + "lane3": "0x008c1c", + "lane4": "0x008c1c", + "lane5": "0x008c1c", + "lane6": "0x008c1c", + "lane7": "0x008c1c" + } + } + }, + "21": { + "Default": { + "preemphasis": { + "lane0": "0x0c8418", + "lane1": "0x0c8418", + "lane2": "0x0c8418", + "lane3": "0x0c8418", + "lane4": "0x0c8418", + "lane5": "0x0c8418", + "lane6": "0x0c8418", + "lane7": "0x0c8418" + } + }, + "QSFP-DD,QSFP28-40GBASE-CR4-1M": { + "preemphasis": { + "lane0": "0x0c8418", + "lane1": "0x0c8418", + "lane2": "0x0c8418", + "lane3": "0x0c8418", + "lane4": "0x0c8418", + "lane5": "0x0c8418", + "lane6": "0x0c8418", + "lane7": "0x0c8418" + } + } + }, + "22": { + "Default": { + "preemphasis": { + "lane0": "0x0c8418", + "lane1": "0x0c8418", + "lane2": "0x0c8418", + "lane3": "0x0c8418", + "lane4": "0x0c8418", + "lane5": "0x0c8418", + "lane6": "0x0c8418", + "lane7": "0x0c8418" + } + }, + "QSFP-DD,QSFP28-40GBASE-CR4-1M": { + "preemphasis": { + "lane0": "0x0c8418", + "lane1": "0x0c8418", + "lane2": "0x0c8418", + "lane3": "0x0c8418", + "lane4": "0x0c8418", + "lane5": "0x0c8418", + "lane6": "0x0c8418", + "lane7": "0x0c8418" + } + } + }, + "23": { + "Default": { + "preemphasis": { + "lane0": "0x0c8418", + "lane1": "0x0c8418", + "lane2": "0x0c8418", + "lane3": "0x0c8418", + "lane4": "0x0c8418", + "lane5": "0x0c8418", + "lane6": "0x0c8418", + "lane7": "0x0c8418" + } + }, + "QSFP-DD,QSFP28-40GBASE-CR4-1M": { + "preemphasis": { + "lane0": "0x0c8418", + "lane1": "0x0c8418", + "lane2": "0x0c8418", + "lane3": "0x0c8418", + "lane4": "0x0c8418", + "lane5": "0x0c8418", + "lane6": "0x0c8418", + "lane7": "0x0c8418" + } + } + }, + "24": { + "Default": { + "preemphasis": { + "lane0": "0x009018", + "lane1": "0x009018", + "lane2": "0x009018", + "lane3": "0x009018", + "lane4": "0x009018", + "lane5": "0x009018", + "lane6": "0x009018", + "lane7": "0x009018" + } + }, + "QSFP-DD,QSFP28-40GBASE-CR4-1M": { + "preemphasis": { + "lane0": "0x009018", + "lane1": "0x009018", + "lane2": "0x009018", + "lane3": "0x009018", + "lane4": "0x009018", + "lane5": "0x009018", + "lane6": "0x009018", + "lane7": "0x009018" + } + } + }, + "25": { + "Default": { + "preemphasis": { + "lane0": "0x009018", + "lane1": "0x009018", + "lane2": "0x009018", + "lane3": "0x009018", + "lane4": "0x009018", + "lane5": "0x009018", + "lane6": "0x009018", + "lane7": "0x009018" + } + }, + "QSFP-DD,QSFP28-40GBASE-CR4-1M": { + "preemphasis": { + "lane0": "0x009018", + "lane1": "0x009018", + "lane2": "0x009018", + "lane3": "0x009018", + "lane4": "0x009018", + "lane5": "0x009018", + "lane6": "0x009018", + "lane7": "0x009018" + } + } + }, + "26": { + "Default": { + "preemphasis": { + "lane0": "0x0c7c18", + "lane1": "0x0c7c18", + "lane2": "0x0c7c18", + "lane3": "0x0c7c18", + "lane4": "0x0c7c18", + "lane5": "0x0c7c18", + "lane6": "0x0c7c18", + "lane7": "0x0c7c18" + } + }, + "QSFP-DD,QSFP28-40GBASE-CR4-1M": { + "preemphasis": { + "lane0": "0x0c7c18", + "lane1": "0x0c7c18", + "lane2": "0x0c7c18", + "lane3": "0x0c7c18", + "lane4": "0x0c7c18", + "lane5": "0x0c7c18", + "lane6": "0x0c7c18", + "lane7": "0x0c7c18" + } + } + }, + "27": { + "Default": { + "preemphasis": { + "lane0": "0x04841c", + "lane1": "0x04841c", + "lane2": "0x04841c", + "lane3": "0x04841c", + "lane4": "0x04841c", + "lane5": "0x04841c", + "lane6": "0x04841c", + "lane7": "0x04841c" + } + }, + "QSFP-DD,QSFP28-40GBASE-CR4-1M": { + "preemphasis": { + "lane0": "0x04841c", + "lane1": "0x04841c", + "lane2": "0x04841c", + "lane3": "0x04841c", + "lane4": "0x04841c", + "lane5": "0x04841c", + "lane6": "0x04841c", + "lane7": "0x04841c" + } + } + }, + "28": { + "Default": { + "preemphasis": { + "lane0": "0x0c8018", + "lane1": "0x0c8018", + "lane2": "0x0c8018", + "lane3": "0x0c8018", + "lane4": "0x0c8018", + "lane5": "0x0c8018", + "lane6": "0x0c8018", + "lane7": "0x0c8018" + } + }, + "QSFP-DD,QSFP28-40GBASE-CR4-1M": { + "preemphasis": { + "lane0": "0x0c8018", + "lane1": "0x0c8018", + "lane2": "0x0c8018", + "lane3": "0x0c8018", + "lane4": "0x0c8018", + "lane5": "0x0c8018", + "lane6": "0x0c8018", + "lane7": "0x0c8018" + } + } + }, + "29": { + "Default": { + "preemphasis": { + "lane0": "0x107c18", + "lane1": "0x107c18", + "lane2": "0x107c18", + "lane3": "0x107c18", + "lane4": "0x107c18", + "lane5": "0x107c18", + "lane6": "0x107c18", + "lane7": "0x107c18" + } + }, + "QSFP-DD,QSFP28-40GBASE-CR4-1M": { + "preemphasis": { + "lane0": "0x107c18", + "lane1": "0x107c18", + "lane2": "0x107c18", + "lane3": "0x107c18", + "lane4": "0x107c18", + "lane5": "0x107c18", + "lane6": "0x107c18", + "lane7": "0x107c18" + } + } + }, + "30": { + "Default": { + "preemphasis": { + "lane0": "0x107818", + "lane1": "0x107818", + "lane2": "0x107818", + "lane3": "0x107818", + "lane4": "0x107818", + "lane5": "0x107818", + "lane6": "0x107818", + "lane7": "0x107818" + } + }, + "QSFP-DD,QSFP28-40GBASE-CR4-1M": { + "preemphasis": { + "lane0": "0x107818", + "lane1": "0x107818", + "lane2": "0x107818", + "lane3": "0x107818", + "lane4": "0x107818", + "lane5": "0x107818", + "lane6": "0x107818", + "lane7": "0x107818" + } + } + }, + "31": { + "Default": { + "preemphasis": { + "lane0": "0x04801c", + "lane1": "0x04801c", + "lane2": "0x04801c", + "lane3": "0x04801c", + "lane4": "0x04801c", + "lane5": "0x04801c", + "lane6": "0x04801c", + "lane7": "0x04801c" + } + }, + "QSFP-DD,QSFP28-40GBASE-CR4-1M": { + "preemphasis": { + "lane0": "0x04801c", + "lane1": "0x04801c", + "lane2": "0x04801c", + "lane3": "0x04801c", + "lane4": "0x04801c", + "lane5": "0x04801c", + "lane6": "0x04801c", + "lane7": "0x04801c" + } + } + } + } +} \ No newline at end of file diff --git a/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/platform_env.conf b/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/platform_env.conf new file mode 100755 index 0000000000..c8c09ab2d9 --- /dev/null +++ b/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/platform_env.conf @@ -0,0 +1,2 @@ +dmasize=32M +usemsi=0 diff --git a/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/plugins/eeprom.py b/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/plugins/eeprom.py new file mode 100755 index 0000000000..10df5bb12c --- /dev/null +++ b/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/plugins/eeprom.py @@ -0,0 +1,16 @@ +#!/usr/bin/env python + +try: + import os + from sonic_eeprom import eeprom_tlvinfo +except ImportError, e: + raise ImportError (str(e) + "- required module not found") + +class board(eeprom_tlvinfo.TlvInfoDecoder): + _TLV_INFO_MAX_LEN = 256 + def __init__(self, name, path, cpld_root, ro): + self.eeprom_path = "/sys/bus/i2c/devices/1-0056/eeprom" + #Two i2c buses might get flipped order, check them both. + if not os.path.exists(self.eeprom_path): + self.eeprom_path = "/sys/bus/i2c/devices/0-0056/eeprom" + super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/plugins/led_control.py b/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/plugins/led_control.py new file mode 100755 index 0000000000..6bb9faf460 --- /dev/null +++ b/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/plugins/led_control.py @@ -0,0 +1,119 @@ +#!/usr/bin/env python +# +# led_control.py +# +# Platform-specific LED control functionality for SONiC +# + +# try: +# from sonic_led.led_control_base import LedControlBase +# import swsssdk +# except ImportError, e: +# raise ImportError (str(e) + " - required module not found") + +import time +import glob +import os.path + +class LedControlBase(object): +# __metaclass__ = abc.ABCMeta + +# @abc.abstractmethod + def port_link_state_change(self, port, state): + """ + Called when port link state changes. Update port link state LED here. + + :param port: A string, SONiC port name (e.g., "Ethernet0") + :param state: A string, the port link state (either "up" or "down") + """ + return + +### Goreme specified ### +read_fan_fault = 0 +is_fan_all_OK = 0 +read_power_status = 0 +is_power_all_OK = 0 +is_thermal_high = 0 +is_reset_button_push = 0 +########################## + +def sysled_task(): + while True: + system_led_check() + time.sleep(5) + +########## Goreme System LED checking +def system_led_check(): + global read_fan_fault, read_power_status, is_fan_all_OK, is_power_all_OK, is_thermal_high, is_reset_button_push + is_fan_all_OK = 1 + is_power_all_OK = 0 + is_thermal_high = 0 + is_reset_button_push = 0 + + with open("/sys/bus/i2c/devices/0-005e/fan1_led", "r") as f11: + read_fan_led = int(f11.read()) + if read_fan_led == 1: + is_fan_all_OK = 1 + else: + is_fan_all_OK = 0 + + with open("/sys/bus/i2c/devices/0-005e/sys_pwr", "r") as f11: + read_pau_led = int(f11.read()) + if read_pau_led == 1: + is_power_all_OK = 1 + else: + is_power_all_OK = 0 + + if os.path.exists("/sys/bus/i2c/devices/3-004d/hwmon/"): + with open("/sys/bus/i2c/devices/3-004d/hwmon/hwmon2/temp1_input", "r") as f3: + is_thermal_high = f3.read() + if int(is_thermal_high) >= 70000: + is_thermal_high = 1 + else: + is_thermal_high = 0 + else: + node = glob.glob("/sys/bus/i2c/devices/18-004d/hwmon/hwmon*") + node = node[0] + "/temp1_input" + with open(node, "r") as f3: + is_thermal_high = f3.read() + if int(is_thermal_high) >= 70000: + is_thermal_high = 1 + else: + is_thermal_high = 0 + + with open("/sys/bus/i2c/devices/0-005e/sys_status", "w") as f2: + if is_reset_button_push == 1: + f2.write("3") + elif is_fan_all_OK == 0 or is_power_all_OK == 0 or is_thermal_high == 1: + f2.write("4") + else: + f2.write("1") + + return +########## + + +class LedControl(LedControlBase): + """Platform specific LED control class""" + + # Constructor + def __init__(self): + # Initialize all front-panel status LEDs to green + with open("/sys/bus/i2c/devices/0-005e/sys_locator", "w") as f: + f.write("1") + with open("/sys/bus/i2c/devices/0-005e/sys_status", "w") as f: + f.write("1") + + sysled_task() + + # Initialize: Turn all front panel QSFP LEDs off + # # for qsfp_index in range(self.QSFP_BREAKOUT_START_IDX, self.QSFP_BREAKOUT_END_IDX + 1): + # # for lane in range(1, 5): + # # led_sysfs_path = self.LED_SYSFS_PATH_BREAKOUT_CAPABLE.format(qsfp_index, lane) + # # with open(led_sysfs_path, 'w') as led_file: + # # led_file.write("%d" % self.LED_COLOR_OFF) + + # # for qsfp_index in range(self.QSFP_NO_BREAKOUT_START_IDX, self.QSFP_NO_BREAKOUT_END_IDX + 1): + # # led_sysfs_path = self.LED_SYSFS_PATH_NO_BREAKOUT.format(qsfp_index) + # # with open(led_sysfs_path, 'w') as led_file: + # # led_file.write("%d" % self.LED_COLOR_OFF) diff --git a/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/pmon_daemon_control.json b/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/pmon_daemon_control.json new file mode 100755 index 0000000000..6453cd2c5d --- /dev/null +++ b/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/pmon_daemon_control.json @@ -0,0 +1,4 @@ +{ + "skip_fancontrol": true +} + diff --git a/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/preemphasis-32x400G.soc b/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/preemphasis-32x400G.soc new file mode 100755 index 0000000000..652d901fc3 --- /dev/null +++ b/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/preemphasis-32x400G.soc @@ -0,0 +1,1313 @@ +# Preemphasis + +phy raw c45 0x81 0x1 0xffde 0 +phy raw c45 0x81 0x1 0xd133 0x1000 +phy raw c45 0x81 0x1 0xd134 0x1e8 +phy raw c45 0x81 0x1 0xd135 0x84 +phy raw c45 0x81 0x1 0xd136 0x1f4 +phy raw c45 0x81 0x1 0xffde 1 +phy raw c45 0x81 0x1 0xd133 0x1000 +phy raw c45 0x81 0x1 0xd134 0x1e8 +phy raw c45 0x81 0x1 0xd135 0x84 +phy raw c45 0x81 0x1 0xd136 0x1f4 +phy raw c45 0x81 0x1 0xffde 2 +phy raw c45 0x81 0x1 0xd133 0x1000 +phy raw c45 0x81 0x1 0xd134 0x1e8 +phy raw c45 0x81 0x1 0xd135 0x84 +phy raw c45 0x81 0x1 0xd136 0x1f4 +phy raw c45 0x81 0x1 0xffde 3 +phy raw c45 0x81 0x1 0xd133 0x1000 +phy raw c45 0x81 0x1 0xd134 0x1e8 +phy raw c45 0x81 0x1 0xd135 0x84 +phy raw c45 0x81 0x1 0xd136 0x1f4 +phy raw c45 0x81 0x1 0xffde 4 +phy raw c45 0x81 0x1 0xd133 0x1000 +phy raw c45 0x81 0x1 0xd134 0x1e8 +phy raw c45 0x81 0x1 0xd135 0x84 +phy raw c45 0x81 0x1 0xd136 0x1f4 +phy raw c45 0x81 0x1 0xffde 5 +phy raw c45 0x81 0x1 0xd133 0x1000 +phy raw c45 0x81 0x1 0xd134 0x1e8 +phy raw c45 0x81 0x1 0xd135 0x84 +phy raw c45 0x81 0x1 0xd136 0x1f4 +phy raw c45 0x81 0x1 0xffde 6 +phy raw c45 0x81 0x1 0xd133 0x1000 +phy raw c45 0x81 0x1 0xd134 0x1e8 +phy raw c45 0x81 0x1 0xd135 0x84 +phy raw c45 0x81 0x1 0xd136 0x1f4 +phy raw c45 0x81 0x1 0xffde 7 +phy raw c45 0x81 0x1 0xd133 0x1000 +phy raw c45 0x81 0x1 0xd134 0x1e8 +phy raw c45 0x81 0x1 0xd135 0x84 +phy raw c45 0x81 0x1 0xd136 0x1f4 + +phy raw c45 0x89 0x1 0xffde 0 +phy raw c45 0x89 0x1 0xd133 0x1000 +phy raw c45 0x89 0x1 0xd134 0x1e8 +phy raw c45 0x89 0x1 0xd135 0x84 +phy raw c45 0x89 0x1 0xd136 0x1f4 +phy raw c45 0x89 0x1 0xffde 1 +phy raw c45 0x89 0x1 0xd133 0x1000 +phy raw c45 0x89 0x1 0xd134 0x1e8 +phy raw c45 0x89 0x1 0xd135 0x84 +phy raw c45 0x89 0x1 0xd136 0x1f4 +phy raw c45 0x89 0x1 0xffde 2 +phy raw c45 0x89 0x1 0xd133 0x1000 +phy raw c45 0x89 0x1 0xd134 0x1e8 +phy raw c45 0x89 0x1 0xd135 0x84 +phy raw c45 0x89 0x1 0xd136 0x1f4 +phy raw c45 0x89 0x1 0xffde 3 +phy raw c45 0x89 0x1 0xd133 0x1000 +phy raw c45 0x89 0x1 0xd134 0x1e8 +phy raw c45 0x89 0x1 0xd135 0x84 +phy raw c45 0x89 0x1 0xd136 0x1f4 +phy raw c45 0x89 0x1 0xffde 4 +phy raw c45 0x89 0x1 0xd133 0x1000 +phy raw c45 0x89 0x1 0xd134 0x1e8 +phy raw c45 0x89 0x1 0xd135 0x84 +phy raw c45 0x89 0x1 0xd136 0x1f4 +phy raw c45 0x89 0x1 0xffde 5 +phy raw c45 0x89 0x1 0xd133 0x1000 +phy raw c45 0x89 0x1 0xd134 0x1e8 +phy raw c45 0x89 0x1 0xd135 0x84 +phy raw c45 0x89 0x1 0xd136 0x1f4 +phy raw c45 0x89 0x1 0xffde 6 +phy raw c45 0x89 0x1 0xd133 0x1000 +phy raw c45 0x89 0x1 0xd134 0x1e8 +phy raw c45 0x89 0x1 0xd135 0x84 +phy raw c45 0x89 0x1 0xd136 0x1f4 +phy raw c45 0x89 0x1 0xffde 7 +phy raw c45 0x89 0x1 0xd133 0x1000 +phy raw c45 0x89 0x1 0xd134 0x1e8 +phy raw c45 0x89 0x1 0xd135 0x84 +phy raw c45 0x89 0x1 0xd136 0x1f4 + +phy raw c45 0x91 0x1 0xffde 0 +phy raw c45 0x91 0x1 0xd133 0x1006 +phy raw c45 0x91 0x1 0xd134 0x1e4 +phy raw c45 0x91 0x1 0xd135 0x70 +phy raw c45 0x91 0x1 0xd136 0x1f4 +phy raw c45 0x91 0x1 0xffde 1 +phy raw c45 0x91 0x1 0xd133 0x1006 +phy raw c45 0x91 0x1 0xd134 0x1e4 +phy raw c45 0x91 0x1 0xd135 0x70 +phy raw c45 0x91 0x1 0xd136 0x1f4 +phy raw c45 0x91 0x1 0xffde 2 +phy raw c45 0x91 0x1 0xd133 0x1006 +phy raw c45 0x91 0x1 0xd134 0x1e4 +phy raw c45 0x91 0x1 0xd135 0x70 +phy raw c45 0x91 0x1 0xd136 0x1f4 +phy raw c45 0x91 0x1 0xffde 3 +phy raw c45 0x91 0x1 0xd133 0x1006 +phy raw c45 0x91 0x1 0xd134 0x1e4 +phy raw c45 0x91 0x1 0xd135 0x70 +phy raw c45 0x91 0x1 0xd136 0x1f4 +phy raw c45 0x91 0x1 0xffde 4 +phy raw c45 0x91 0x1 0xd133 0x1006 +phy raw c45 0x91 0x1 0xd134 0x1e4 +phy raw c45 0x91 0x1 0xd135 0x70 +phy raw c45 0x91 0x1 0xd136 0x1f4 +phy raw c45 0x91 0x1 0xffde 5 +phy raw c45 0x91 0x1 0xd133 0x1006 +phy raw c45 0x91 0x1 0xd134 0x1e4 +phy raw c45 0x91 0x1 0xd135 0x70 +phy raw c45 0x91 0x1 0xd136 0x1f4 +phy raw c45 0x91 0x1 0xffde 6 +phy raw c45 0x91 0x1 0xd133 0x1006 +phy raw c45 0x91 0x1 0xd134 0x1e4 +phy raw c45 0x91 0x1 0xd135 0x70 +phy raw c45 0x91 0x1 0xd136 0x1f4 +phy raw c45 0x91 0x1 0xffde 7 +phy raw c45 0x91 0x1 0xd133 0x1006 +phy raw c45 0x91 0x1 0xd134 0x1e4 +phy raw c45 0x91 0x1 0xd135 0x70 +phy raw c45 0x91 0x1 0xd136 0x1f4 + +phy raw c45 0xa1 0x1 0xffde 0 +phy raw c45 0xa1 0x1 0xd133 0x1004 +phy raw c45 0xa1 0x1 0xd134 0x1e4 +phy raw c45 0xa1 0x1 0xd135 0x74 +phy raw c45 0xa1 0x1 0xd136 0x1f0 +phy raw c45 0xa1 0x1 0xffde 1 +phy raw c45 0xa1 0x1 0xd133 0x1004 +phy raw c45 0xa1 0x1 0xd134 0x1e4 +phy raw c45 0xa1 0x1 0xd135 0x74 +phy raw c45 0xa1 0x1 0xd136 0x1f0 +phy raw c45 0xa1 0x1 0xffde 2 +phy raw c45 0xa1 0x1 0xd133 0x1004 +phy raw c45 0xa1 0x1 0xd134 0x1e4 +phy raw c45 0xa1 0x1 0xd135 0x74 +phy raw c45 0xa1 0x1 0xd136 0x1f0 +phy raw c45 0xa1 0x1 0xffde 3 +phy raw c45 0xa1 0x1 0xd133 0x1004 +phy raw c45 0xa1 0x1 0xd134 0x1e4 +phy raw c45 0xa1 0x1 0xd135 0x74 +phy raw c45 0xa1 0x1 0xd136 0x1f0 +phy raw c45 0xa1 0x1 0xffde 4 +phy raw c45 0xa1 0x1 0xd133 0x1004 +phy raw c45 0xa1 0x1 0xd134 0x1e4 +phy raw c45 0xa1 0x1 0xd135 0x74 +phy raw c45 0xa1 0x1 0xd136 0x1f0 +phy raw c45 0xa1 0x1 0xffde 5 +phy raw c45 0xa1 0x1 0xd133 0x1004 +phy raw c45 0xa1 0x1 0xd134 0x1e4 +phy raw c45 0xa1 0x1 0xd135 0x74 +phy raw c45 0xa1 0x1 0xd136 0x1f0 +phy raw c45 0xa1 0x1 0xffde 6 +phy raw c45 0xa1 0x1 0xd133 0x1004 +phy raw c45 0xa1 0x1 0xd134 0x1e4 +phy raw c45 0xa1 0x1 0xd135 0x74 +phy raw c45 0xa1 0x1 0xd136 0x1f0 +phy raw c45 0xa1 0x1 0xffde 7 +phy raw c45 0xa1 0x1 0xd133 0x1004 +phy raw c45 0xa1 0x1 0xd134 0x1e4 +phy raw c45 0xa1 0x1 0xd135 0x74 +phy raw c45 0xa1 0x1 0xd136 0x1f0 + +phy raw c45 0xa9 0x1 0xffde 0 +phy raw c45 0xa9 0x1 0xd133 0x1004 +phy raw c45 0xa9 0x1 0xd134 0x1e4 +phy raw c45 0xa9 0x1 0xd135 0x78 +phy raw c45 0xa9 0x1 0xd136 0x1f4 +phy raw c45 0xa9 0x1 0xffde 1 +phy raw c45 0xa9 0x1 0xd133 0x1004 +phy raw c45 0xa9 0x1 0xd134 0x1e4 +phy raw c45 0xa9 0x1 0xd135 0x78 +phy raw c45 0xa9 0x1 0xd136 0x1f4 +phy raw c45 0xa9 0x1 0xffde 2 +phy raw c45 0xa9 0x1 0xd133 0x1004 +phy raw c45 0xa9 0x1 0xd134 0x1e4 +phy raw c45 0xa9 0x1 0xd135 0x78 +phy raw c45 0xa9 0x1 0xd136 0x1f4 +phy raw c45 0xa9 0x1 0xffde 3 +phy raw c45 0xa9 0x1 0xd133 0x1004 +phy raw c45 0xa9 0x1 0xd134 0x1e4 +phy raw c45 0xa9 0x1 0xd135 0x78 +phy raw c45 0xa9 0x1 0xd136 0x1f4 +phy raw c45 0xa9 0x1 0xffde 4 +phy raw c45 0xa9 0x1 0xd133 0x1004 +phy raw c45 0xa9 0x1 0xd134 0x1e4 +phy raw c45 0xa9 0x1 0xd135 0x78 +phy raw c45 0xa9 0x1 0xd136 0x1f4 +phy raw c45 0xa9 0x1 0xffde 5 +phy raw c45 0xa9 0x1 0xd133 0x1004 +phy raw c45 0xa9 0x1 0xd134 0x1e4 +phy raw c45 0xa9 0x1 0xd135 0x78 +phy raw c45 0xa9 0x1 0xd136 0x1f4 +phy raw c45 0xa9 0x1 0xffde 6 +phy raw c45 0xa9 0x1 0xd133 0x1004 +phy raw c45 0xa9 0x1 0xd134 0x1e4 +phy raw c45 0xa9 0x1 0xd135 0x78 +phy raw c45 0xa9 0x1 0xd136 0x1f4 +phy raw c45 0xa9 0x1 0xffde 7 +phy raw c45 0xa9 0x1 0xd133 0x1004 +phy raw c45 0xa9 0x1 0xd134 0x1e4 +phy raw c45 0xa9 0x1 0xd135 0x78 +phy raw c45 0xa9 0x1 0xd136 0x1f4 + +phy raw c45 0xb1 0x1 0xffde 0 +phy raw c45 0xb1 0x1 0xd133 0x1004 +phy raw c45 0xb1 0x1 0xd134 0x1e8 +phy raw c45 0xb1 0x1 0xd135 0x7c +phy raw c45 0xb1 0x1 0xd136 0x1f4 +phy raw c45 0xb1 0x1 0xffde 1 +phy raw c45 0xb1 0x1 0xd133 0x1004 +phy raw c45 0xb1 0x1 0xd134 0x1e8 +phy raw c45 0xb1 0x1 0xd135 0x7c +phy raw c45 0xb1 0x1 0xd136 0x1f4 +phy raw c45 0xb1 0x1 0xffde 2 +phy raw c45 0xb1 0x1 0xd133 0x1004 +phy raw c45 0xb1 0x1 0xd134 0x1e8 +phy raw c45 0xb1 0x1 0xd135 0x7c +phy raw c45 0xb1 0x1 0xd136 0x1f4 +phy raw c45 0xb1 0x1 0xffde 3 +phy raw c45 0xb1 0x1 0xd133 0x1004 +phy raw c45 0xb1 0x1 0xd134 0x1e8 +phy raw c45 0xb1 0x1 0xd135 0x7c +phy raw c45 0xb1 0x1 0xd136 0x1f4 +phy raw c45 0xb1 0x1 0xffde 4 +phy raw c45 0xb1 0x1 0xd133 0x1004 +phy raw c45 0xb1 0x1 0xd134 0x1e8 +phy raw c45 0xb1 0x1 0xd135 0x7c +phy raw c45 0xb1 0x1 0xd136 0x1f4 +phy raw c45 0xb1 0x1 0xffde 5 +phy raw c45 0xb1 0x1 0xd133 0x1004 +phy raw c45 0xb1 0x1 0xd134 0x1e8 +phy raw c45 0xb1 0x1 0xd135 0x7c +phy raw c45 0xb1 0x1 0xd136 0x1f4 +phy raw c45 0xb1 0x1 0xffde 6 +phy raw c45 0xb1 0x1 0xd133 0x1004 +phy raw c45 0xb1 0x1 0xd134 0x1e8 +phy raw c45 0xb1 0x1 0xd135 0x7c +phy raw c45 0xb1 0x1 0xd136 0x1f4 +phy raw c45 0xb1 0x1 0xffde 7 +phy raw c45 0xb1 0x1 0xd133 0x1004 +phy raw c45 0xb1 0x1 0xd134 0x1e8 +phy raw c45 0xb1 0x1 0xd135 0x7c +phy raw c45 0xb1 0x1 0xd136 0x1f4 + +phy raw c45 0xc1 0x1 0xffde 0 +phy raw c45 0xc1 0x1 0xd133 0x1004 +phy raw c45 0xc1 0x1 0xd134 0x1e0 +phy raw c45 0xc1 0x1 0xd135 0x80 +phy raw c45 0xc1 0x1 0xd136 0x0 +phy raw c45 0xc1 0x1 0xffde 1 +phy raw c45 0xc1 0x1 0xd133 0x1004 +phy raw c45 0xc1 0x1 0xd134 0x1e0 +phy raw c45 0xc1 0x1 0xd135 0x80 +phy raw c45 0xc1 0x1 0xd136 0x0 +phy raw c45 0xc1 0x1 0xffde 2 +phy raw c45 0xc1 0x1 0xd133 0x1004 +phy raw c45 0xc1 0x1 0xd134 0x1e0 +phy raw c45 0xc1 0x1 0xd135 0x80 +phy raw c45 0xc1 0x1 0xd136 0x0 +phy raw c45 0xc1 0x1 0xffde 3 +phy raw c45 0xc1 0x1 0xd133 0x1004 +phy raw c45 0xc1 0x1 0xd134 0x1e0 +phy raw c45 0xc1 0x1 0xd135 0x80 +phy raw c45 0xc1 0x1 0xd136 0x0 +phy raw c45 0xc1 0x1 0xffde 4 +phy raw c45 0xc1 0x1 0xd133 0x1004 +phy raw c45 0xc1 0x1 0xd134 0x1e0 +phy raw c45 0xc1 0x1 0xd135 0x80 +phy raw c45 0xc1 0x1 0xd136 0x0 +phy raw c45 0xc1 0x1 0xffde 5 +phy raw c45 0xc1 0x1 0xd133 0x1004 +phy raw c45 0xc1 0x1 0xd134 0x1e0 +phy raw c45 0xc1 0x1 0xd135 0x80 +phy raw c45 0xc1 0x1 0xd136 0x0 +phy raw c45 0xc1 0x1 0xffde 6 +phy raw c45 0xc1 0x1 0xd133 0x1004 +phy raw c45 0xc1 0x1 0xd134 0x1e0 +phy raw c45 0xc1 0x1 0xd135 0x80 +phy raw c45 0xc1 0x1 0xd136 0x0 +phy raw c45 0xc1 0x1 0xffde 7 +phy raw c45 0xc1 0x1 0xd133 0x1004 +phy raw c45 0xc1 0x1 0xd134 0x1e0 +phy raw c45 0xc1 0x1 0xd135 0x80 +phy raw c45 0xc1 0x1 0xd136 0x0 + +phy raw c45 0xc9 0x1 0xffde 0 +phy raw c45 0xc9 0x1 0xd133 0x1002 +phy raw c45 0xc9 0x1 0xd134 0x1e4 +phy raw c45 0xc9 0x1 0xd135 0x88 +phy raw c45 0xc9 0x1 0xd136 0x0 +phy raw c45 0xc9 0x1 0xffde 1 +phy raw c45 0xc9 0x1 0xd133 0x1002 +phy raw c45 0xc9 0x1 0xd134 0x1e4 +phy raw c45 0xc9 0x1 0xd135 0x88 +phy raw c45 0xc9 0x1 0xd136 0x0 +phy raw c45 0xc9 0x1 0xffde 2 +phy raw c45 0xc9 0x1 0xd133 0x1002 +phy raw c45 0xc9 0x1 0xd134 0x1e4 +phy raw c45 0xc9 0x1 0xd135 0x88 +phy raw c45 0xc9 0x1 0xd136 0x0 +phy raw c45 0xc9 0x1 0xffde 3 +phy raw c45 0xc9 0x1 0xd133 0x1002 +phy raw c45 0xc9 0x1 0xd134 0x1e4 +phy raw c45 0xc9 0x1 0xd135 0x88 +phy raw c45 0xc9 0x1 0xd136 0x0 +phy raw c45 0xc9 0x1 0xffde 4 +phy raw c45 0xc9 0x1 0xd133 0x1002 +phy raw c45 0xc9 0x1 0xd134 0x1e4 +phy raw c45 0xc9 0x1 0xd135 0x88 +phy raw c45 0xc9 0x1 0xd136 0x0 +phy raw c45 0xc9 0x1 0xffde 5 +phy raw c45 0xc9 0x1 0xd133 0x1002 +phy raw c45 0xc9 0x1 0xd134 0x1e4 +phy raw c45 0xc9 0x1 0xd135 0x88 +phy raw c45 0xc9 0x1 0xd136 0x0 +phy raw c45 0xc9 0x1 0xffde 6 +phy raw c45 0xc9 0x1 0xd133 0x1002 +phy raw c45 0xc9 0x1 0xd134 0x1e4 +phy raw c45 0xc9 0x1 0xd135 0x88 +phy raw c45 0xc9 0x1 0xd136 0x0 +phy raw c45 0xc9 0x1 0xffde 7 +phy raw c45 0xc9 0x1 0xd133 0x1002 +phy raw c45 0xc9 0x1 0xd134 0x1e4 +phy raw c45 0xc9 0x1 0xd135 0x88 +phy raw c45 0xc9 0x1 0xd136 0x0 + +phy raw c45 0xd1 0x1 0xffde 0 +phy raw c45 0xd1 0x1 0xd133 0x1002 +phy raw c45 0xd1 0x1 0xd134 0x1e4 +phy raw c45 0xd1 0x1 0xd135 0x88 +phy raw c45 0xd1 0x1 0xd136 0x0 +phy raw c45 0xd1 0x1 0xffde 1 +phy raw c45 0xd1 0x1 0xd133 0x1002 +phy raw c45 0xd1 0x1 0xd134 0x1e4 +phy raw c45 0xd1 0x1 0xd135 0x88 +phy raw c45 0xd1 0x1 0xd136 0x0 +phy raw c45 0xd1 0x1 0xffde 2 +phy raw c45 0xd1 0x1 0xd133 0x1002 +phy raw c45 0xd1 0x1 0xd134 0x1e4 +phy raw c45 0xd1 0x1 0xd135 0x88 +phy raw c45 0xd1 0x1 0xd136 0x0 +phy raw c45 0xd1 0x1 0xffde 3 +phy raw c45 0xd1 0x1 0xd133 0x1002 +phy raw c45 0xd1 0x1 0xd134 0x1e4 +phy raw c45 0xd1 0x1 0xd135 0x88 +phy raw c45 0xd1 0x1 0xd136 0x0 +phy raw c45 0xd1 0x1 0xffde 4 +phy raw c45 0xd1 0x1 0xd133 0x1002 +phy raw c45 0xd1 0x1 0xd134 0x1e4 +phy raw c45 0xd1 0x1 0xd135 0x88 +phy raw c45 0xd1 0x1 0xd136 0x0 +phy raw c45 0xd1 0x1 0xffde 5 +phy raw c45 0xd1 0x1 0xd133 0x1002 +phy raw c45 0xd1 0x1 0xd134 0x1e4 +phy raw c45 0xd1 0x1 0xd135 0x88 +phy raw c45 0xd1 0x1 0xd136 0x0 +phy raw c45 0xd1 0x1 0xffde 6 +phy raw c45 0xd1 0x1 0xd133 0x1002 +phy raw c45 0xd1 0x1 0xd134 0x1e4 +phy raw c45 0xd1 0x1 0xd135 0x88 +phy raw c45 0xd1 0x1 0xd136 0x0 +phy raw c45 0xd1 0x1 0xffde 7 +phy raw c45 0xd1 0x1 0xd133 0x1002 +phy raw c45 0xd1 0x1 0xd134 0x1e4 +phy raw c45 0xd1 0x1 0xd135 0x88 +phy raw c45 0xd1 0x1 0xd136 0x0 + +phy raw c45 0xe1 0x1 0xffde 0 +phy raw c45 0xe1 0x1 0xd133 0x1000 +phy raw c45 0xe1 0x1 0xd134 0x1e8 +phy raw c45 0xe1 0x1 0xd135 0x90 +phy raw c45 0xe1 0x1 0xd136 0x0 +phy raw c45 0xe1 0x1 0xffde 1 +phy raw c45 0xe1 0x1 0xd133 0x1000 +phy raw c45 0xe1 0x1 0xd134 0x1e8 +phy raw c45 0xe1 0x1 0xd135 0x90 +phy raw c45 0xe1 0x1 0xd136 0x0 +phy raw c45 0xe1 0x1 0xffde 2 +phy raw c45 0xe1 0x1 0xd133 0x1000 +phy raw c45 0xe1 0x1 0xd134 0x1e8 +phy raw c45 0xe1 0x1 0xd135 0x90 +phy raw c45 0xe1 0x1 0xd136 0x0 +phy raw c45 0xe1 0x1 0xffde 3 +phy raw c45 0xe1 0x1 0xd133 0x1000 +phy raw c45 0xe1 0x1 0xd134 0x1e8 +phy raw c45 0xe1 0x1 0xd135 0x90 +phy raw c45 0xe1 0x1 0xd136 0x0 +phy raw c45 0xe1 0x1 0xffde 4 +phy raw c45 0xe1 0x1 0xd133 0x1000 +phy raw c45 0xe1 0x1 0xd134 0x1e8 +phy raw c45 0xe1 0x1 0xd135 0x90 +phy raw c45 0xe1 0x1 0xd136 0x0 +phy raw c45 0xe1 0x1 0xffde 5 +phy raw c45 0xe1 0x1 0xd133 0x1000 +phy raw c45 0xe1 0x1 0xd134 0x1e8 +phy raw c45 0xe1 0x1 0xd135 0x90 +phy raw c45 0xe1 0x1 0xd136 0x0 +phy raw c45 0xe1 0x1 0xffde 6 +phy raw c45 0xe1 0x1 0xd133 0x1000 +phy raw c45 0xe1 0x1 0xd134 0x1e8 +phy raw c45 0xe1 0x1 0xd135 0x90 +phy raw c45 0xe1 0x1 0xd136 0x0 +phy raw c45 0xe1 0x1 0xffde 7 +phy raw c45 0xe1 0x1 0xd133 0x1000 +phy raw c45 0xe1 0x1 0xd134 0x1e8 +phy raw c45 0xe1 0x1 0xd135 0x90 +phy raw c45 0xe1 0x1 0xd136 0x0 + +phy raw c45 0xe9 0x1 0xffde 0 +phy raw c45 0xe9 0x1 0xd133 0x1004 +phy raw c45 0xe9 0x1 0xd134 0x1e4 +phy raw c45 0xe9 0x1 0xd135 0x84 +phy raw c45 0xe9 0x1 0xd136 0x0 +phy raw c45 0xe9 0x1 0xffde 1 +phy raw c45 0xe9 0x1 0xd133 0x1004 +phy raw c45 0xe9 0x1 0xd134 0x1e4 +phy raw c45 0xe9 0x1 0xd135 0x84 +phy raw c45 0xe9 0x1 0xd136 0x0 +phy raw c45 0xe9 0x1 0xffde 2 +phy raw c45 0xe9 0x1 0xd133 0x1004 +phy raw c45 0xe9 0x1 0xd134 0x1e4 +phy raw c45 0xe9 0x1 0xd135 0x84 +phy raw c45 0xe9 0x1 0xd136 0x0 +phy raw c45 0xe9 0x1 0xffde 3 +phy raw c45 0xe9 0x1 0xd133 0x1004 +phy raw c45 0xe9 0x1 0xd134 0x1e4 +phy raw c45 0xe9 0x1 0xd135 0x84 +phy raw c45 0xe9 0x1 0xd136 0x0 +phy raw c45 0xe9 0x1 0xffde 4 +phy raw c45 0xe9 0x1 0xd133 0x1004 +phy raw c45 0xe9 0x1 0xd134 0x1e4 +phy raw c45 0xe9 0x1 0xd135 0x84 +phy raw c45 0xe9 0x1 0xd136 0x0 +phy raw c45 0xe9 0x1 0xffde 5 +phy raw c45 0xe9 0x1 0xd133 0x1004 +phy raw c45 0xe9 0x1 0xd134 0x1e4 +phy raw c45 0xe9 0x1 0xd135 0x84 +phy raw c45 0xe9 0x1 0xd136 0x0 +phy raw c45 0xe9 0x1 0xffde 6 +phy raw c45 0xe9 0x1 0xd133 0x1004 +phy raw c45 0xe9 0x1 0xd134 0x1e4 +phy raw c45 0xe9 0x1 0xd135 0x84 +phy raw c45 0xe9 0x1 0xd136 0x0 +phy raw c45 0xe9 0x1 0xffde 7 +phy raw c45 0xe9 0x1 0xd133 0x1004 +phy raw c45 0xe9 0x1 0xd134 0x1e4 +phy raw c45 0xe9 0x1 0xd135 0x84 +phy raw c45 0xe9 0x1 0xd136 0x0 + +phy raw c45 0xf1 0x1 0xffde 0 +phy raw c45 0xf1 0x1 0xd133 0x1000 +phy raw c45 0xf1 0x1 0xd134 0x1e8 +phy raw c45 0xf1 0x1 0xd135 0x90 +phy raw c45 0xf1 0x1 0xd136 0x0 +phy raw c45 0xf1 0x1 0xffde 1 +phy raw c45 0xf1 0x1 0xd133 0x1000 +phy raw c45 0xf1 0x1 0xd134 0x1e8 +phy raw c45 0xf1 0x1 0xd135 0x90 +phy raw c45 0xf1 0x1 0xd136 0x0 +phy raw c45 0xf1 0x1 0xffde 2 +phy raw c45 0xf1 0x1 0xd133 0x1000 +phy raw c45 0xf1 0x1 0xd134 0x1e8 +phy raw c45 0xf1 0x1 0xd135 0x90 +phy raw c45 0xf1 0x1 0xd136 0x0 +phy raw c45 0xf1 0x1 0xffde 3 +phy raw c45 0xf1 0x1 0xd133 0x1000 +phy raw c45 0xf1 0x1 0xd134 0x1e8 +phy raw c45 0xf1 0x1 0xd135 0x90 +phy raw c45 0xf1 0x1 0xd136 0x0 +phy raw c45 0xf1 0x1 0xffde 4 +phy raw c45 0xf1 0x1 0xd133 0x1000 +phy raw c45 0xf1 0x1 0xd134 0x1e8 +phy raw c45 0xf1 0x1 0xd135 0x90 +phy raw c45 0xf1 0x1 0xd136 0x0 +phy raw c45 0xf1 0x1 0xffde 5 +phy raw c45 0xf1 0x1 0xd133 0x1000 +phy raw c45 0xf1 0x1 0xd134 0x1e8 +phy raw c45 0xf1 0x1 0xd135 0x90 +phy raw c45 0xf1 0x1 0xd136 0x0 +phy raw c45 0xf1 0x1 0xffde 6 +phy raw c45 0xf1 0x1 0xd133 0x1000 +phy raw c45 0xf1 0x1 0xd134 0x1e8 +phy raw c45 0xf1 0x1 0xd135 0x90 +phy raw c45 0xf1 0x1 0xd136 0x0 +phy raw c45 0xf1 0x1 0xffde 7 +phy raw c45 0xf1 0x1 0xd133 0x1000 +phy raw c45 0xf1 0x1 0xd134 0x1e8 +phy raw c45 0xf1 0x1 0xd135 0x90 +phy raw c45 0xf1 0x1 0xd136 0x0 + +phy raw c45 0x181 0x1 0xffde 0 +phy raw c45 0x181 0x1 0xd133 0x1000 +phy raw c45 0x181 0x1 0xd134 0x1e4 +phy raw c45 0x181 0x1 0xd135 0x8c +phy raw c45 0x181 0x1 0xd136 0x0 +phy raw c45 0x181 0x1 0xffde 1 +phy raw c45 0x181 0x1 0xd133 0x1000 +phy raw c45 0x181 0x1 0xd134 0x1e4 +phy raw c45 0x181 0x1 0xd135 0x8c +phy raw c45 0x181 0x1 0xd136 0x0 +phy raw c45 0x181 0x1 0xffde 2 +phy raw c45 0x181 0x1 0xd133 0x1000 +phy raw c45 0x181 0x1 0xd134 0x1e4 +phy raw c45 0x181 0x1 0xd135 0x8c +phy raw c45 0x181 0x1 0xd136 0x0 +phy raw c45 0x181 0x1 0xffde 3 +phy raw c45 0x181 0x1 0xd133 0x1000 +phy raw c45 0x181 0x1 0xd134 0x1e4 +phy raw c45 0x181 0x1 0xd135 0x8c +phy raw c45 0x181 0x1 0xd136 0x0 +phy raw c45 0x181 0x1 0xffde 4 +phy raw c45 0x181 0x1 0xd133 0x1000 +phy raw c45 0x181 0x1 0xd134 0x1e4 +phy raw c45 0x181 0x1 0xd135 0x8c +phy raw c45 0x181 0x1 0xd136 0x0 +phy raw c45 0x181 0x1 0xffde 5 +phy raw c45 0x181 0x1 0xd133 0x1000 +phy raw c45 0x181 0x1 0xd134 0x1e4 +phy raw c45 0x181 0x1 0xd135 0x8c +phy raw c45 0x181 0x1 0xd136 0x0 +phy raw c45 0x181 0x1 0xffde 6 +phy raw c45 0x181 0x1 0xd133 0x1000 +phy raw c45 0x181 0x1 0xd134 0x1e4 +phy raw c45 0x181 0x1 0xd135 0x8c +phy raw c45 0x181 0x1 0xd136 0x0 +phy raw c45 0x181 0x1 0xffde 7 +phy raw c45 0x181 0x1 0xd133 0x1000 +phy raw c45 0x181 0x1 0xd134 0x1e4 +phy raw c45 0x181 0x1 0xd135 0x8c +phy raw c45 0x181 0x1 0xd136 0x0 + +phy raw c45 0x189 0x1 0xffde 0 +phy raw c45 0x189 0x1 0xd133 0x1000 +phy raw c45 0x189 0x1 0xd134 0x1e8 +phy raw c45 0x189 0x1 0xd135 0x90 +phy raw c45 0x189 0x1 0xd136 0x0 +phy raw c45 0x189 0x1 0xffde 1 +phy raw c45 0x189 0x1 0xd133 0x1000 +phy raw c45 0x189 0x1 0xd134 0x1e8 +phy raw c45 0x189 0x1 0xd135 0x90 +phy raw c45 0x189 0x1 0xd136 0x0 +phy raw c45 0x189 0x1 0xffde 2 +phy raw c45 0x189 0x1 0xd133 0x1000 +phy raw c45 0x189 0x1 0xd134 0x1e8 +phy raw c45 0x189 0x1 0xd135 0x90 +phy raw c45 0x189 0x1 0xd136 0x0 +phy raw c45 0x189 0x1 0xffde 3 +phy raw c45 0x189 0x1 0xd133 0x1000 +phy raw c45 0x189 0x1 0xd134 0x1e8 +phy raw c45 0x189 0x1 0xd135 0x90 +phy raw c45 0x189 0x1 0xd136 0x0 +phy raw c45 0x189 0x1 0xffde 4 +phy raw c45 0x189 0x1 0xd133 0x1000 +phy raw c45 0x189 0x1 0xd134 0x1e8 +phy raw c45 0x189 0x1 0xd135 0x90 +phy raw c45 0x189 0x1 0xd136 0x0 +phy raw c45 0x189 0x1 0xffde 5 +phy raw c45 0x189 0x1 0xd133 0x1000 +phy raw c45 0x189 0x1 0xd134 0x1e8 +phy raw c45 0x189 0x1 0xd135 0x90 +phy raw c45 0x189 0x1 0xd136 0x0 +phy raw c45 0x189 0x1 0xffde 6 +phy raw c45 0x189 0x1 0xd133 0x1000 +phy raw c45 0x189 0x1 0xd134 0x1e8 +phy raw c45 0x189 0x1 0xd135 0x90 +phy raw c45 0x189 0x1 0xd136 0x0 +phy raw c45 0x189 0x1 0xffde 7 +phy raw c45 0x189 0x1 0xd133 0x1000 +phy raw c45 0x189 0x1 0xd134 0x1e8 +phy raw c45 0x189 0x1 0xd135 0x90 +phy raw c45 0x189 0x1 0xd136 0x0 + +phy raw c45 0x191 0x1 0xffde 0 +phy raw c45 0x191 0x1 0xd133 0x1000 +phy raw c45 0x191 0x1 0xd134 0x1e8 +phy raw c45 0x191 0x1 0xd135 0x84 +phy raw c45 0x191 0x1 0xd136 0x1f4 +phy raw c45 0x191 0x1 0xffde 1 +phy raw c45 0x191 0x1 0xd133 0x1000 +phy raw c45 0x191 0x1 0xd134 0x1e8 +phy raw c45 0x191 0x1 0xd135 0x84 +phy raw c45 0x191 0x1 0xd136 0x1f4 +phy raw c45 0x191 0x1 0xffde 2 +phy raw c45 0x191 0x1 0xd133 0x1000 +phy raw c45 0x191 0x1 0xd134 0x1e8 +phy raw c45 0x191 0x1 0xd135 0x84 +phy raw c45 0x191 0x1 0xd136 0x1f4 +phy raw c45 0x191 0x1 0xffde 3 +phy raw c45 0x191 0x1 0xd133 0x1000 +phy raw c45 0x191 0x1 0xd134 0x1e8 +phy raw c45 0x191 0x1 0xd135 0x84 +phy raw c45 0x191 0x1 0xd136 0x1f4 +phy raw c45 0x191 0x1 0xffde 4 +phy raw c45 0x191 0x1 0xd133 0x1000 +phy raw c45 0x191 0x1 0xd134 0x1e8 +phy raw c45 0x191 0x1 0xd135 0x84 +phy raw c45 0x191 0x1 0xd136 0x1f4 +phy raw c45 0x191 0x1 0xffde 5 +phy raw c45 0x191 0x1 0xd133 0x1000 +phy raw c45 0x191 0x1 0xd134 0x1e8 +phy raw c45 0x191 0x1 0xd135 0x84 +phy raw c45 0x191 0x1 0xd136 0x1f4 +phy raw c45 0x191 0x1 0xffde 6 +phy raw c45 0x191 0x1 0xd133 0x1000 +phy raw c45 0x191 0x1 0xd134 0x1e8 +phy raw c45 0x191 0x1 0xd135 0x84 +phy raw c45 0x191 0x1 0xd136 0x1f4 +phy raw c45 0x191 0x1 0xffde 7 +phy raw c45 0x191 0x1 0xd133 0x1000 +phy raw c45 0x191 0x1 0xd134 0x1e8 +phy raw c45 0x191 0x1 0xd135 0x84 +phy raw c45 0x191 0x1 0xd136 0x1f4 + +phy raw c45 0x1a1 0x1 0xffde 0 +phy raw c45 0x1a1 0x1 0xd133 0x1000 +phy raw c45 0x1a1 0x1 0xd134 0x1e8 +phy raw c45 0x1a1 0x1 0xd135 0x84 +phy raw c45 0x1a1 0x1 0xd136 0x1f4 +phy raw c45 0x1a1 0x1 0xffde 1 +phy raw c45 0x1a1 0x1 0xd133 0x1000 +phy raw c45 0x1a1 0x1 0xd134 0x1e8 +phy raw c45 0x1a1 0x1 0xd135 0x84 +phy raw c45 0x1a1 0x1 0xd136 0x1f4 +phy raw c45 0x1a1 0x1 0xffde 2 +phy raw c45 0x1a1 0x1 0xd133 0x1000 +phy raw c45 0x1a1 0x1 0xd134 0x1e8 +phy raw c45 0x1a1 0x1 0xd135 0x84 +phy raw c45 0x1a1 0x1 0xd136 0x1f4 +phy raw c45 0x1a1 0x1 0xffde 3 +phy raw c45 0x1a1 0x1 0xd133 0x1000 +phy raw c45 0x1a1 0x1 0xd134 0x1e8 +phy raw c45 0x1a1 0x1 0xd135 0x84 +phy raw c45 0x1a1 0x1 0xd136 0x1f4 +phy raw c45 0x1a1 0x1 0xffde 4 +phy raw c45 0x1a1 0x1 0xd133 0x1000 +phy raw c45 0x1a1 0x1 0xd134 0x1e8 +phy raw c45 0x1a1 0x1 0xd135 0x84 +phy raw c45 0x1a1 0x1 0xd136 0x1f4 +phy raw c45 0x1a1 0x1 0xffde 5 +phy raw c45 0x1a1 0x1 0xd133 0x1000 +phy raw c45 0x1a1 0x1 0xd134 0x1e8 +phy raw c45 0x1a1 0x1 0xd135 0x84 +phy raw c45 0x1a1 0x1 0xd136 0x1f4 +phy raw c45 0x1a1 0x1 0xffde 6 +phy raw c45 0x1a1 0x1 0xd133 0x1000 +phy raw c45 0x1a1 0x1 0xd134 0x1e8 +phy raw c45 0x1a1 0x1 0xd135 0x84 +phy raw c45 0x1a1 0x1 0xd136 0x1f4 +phy raw c45 0x1a1 0x1 0xffde 7 +phy raw c45 0x1a1 0x1 0xd133 0x1000 +phy raw c45 0x1a1 0x1 0xd134 0x1e8 +phy raw c45 0x1a1 0x1 0xd135 0x84 +phy raw c45 0x1a1 0x1 0xd136 0x1f4 + +phy raw c45 0x1a9 0x1 0xffde 0 +phy raw c45 0x1a9 0x1 0xd133 0x1000 +phy raw c45 0x1a9 0x1 0xd134 0x1e8 +phy raw c45 0x1a9 0x1 0xd135 0x90 +phy raw c45 0x1a9 0x1 0xd136 0x0 +phy raw c45 0x1a9 0x1 0xffde 1 +phy raw c45 0x1a9 0x1 0xd133 0x1000 +phy raw c45 0x1a9 0x1 0xd134 0x1e8 +phy raw c45 0x1a9 0x1 0xd135 0x90 +phy raw c45 0x1a9 0x1 0xd136 0x0 +phy raw c45 0x1a9 0x1 0xffde 2 +phy raw c45 0x1a9 0x1 0xd133 0x1000 +phy raw c45 0x1a9 0x1 0xd134 0x1e8 +phy raw c45 0x1a9 0x1 0xd135 0x90 +phy raw c45 0x1a9 0x1 0xd136 0x0 +phy raw c45 0x1a9 0x1 0xffde 3 +phy raw c45 0x1a9 0x1 0xd133 0x1000 +phy raw c45 0x1a9 0x1 0xd134 0x1e8 +phy raw c45 0x1a9 0x1 0xd135 0x90 +phy raw c45 0x1a9 0x1 0xd136 0x0 +phy raw c45 0x1a9 0x1 0xffde 4 +phy raw c45 0x1a9 0x1 0xd133 0x1000 +phy raw c45 0x1a9 0x1 0xd134 0x1e8 +phy raw c45 0x1a9 0x1 0xd135 0x90 +phy raw c45 0x1a9 0x1 0xd136 0x0 +phy raw c45 0x1a9 0x1 0xffde 5 +phy raw c45 0x1a9 0x1 0xd133 0x1000 +phy raw c45 0x1a9 0x1 0xd134 0x1e8 +phy raw c45 0x1a9 0x1 0xd135 0x90 +phy raw c45 0x1a9 0x1 0xd136 0x0 +phy raw c45 0x1a9 0x1 0xffde 6 +phy raw c45 0x1a9 0x1 0xd133 0x1000 +phy raw c45 0x1a9 0x1 0xd134 0x1e8 +phy raw c45 0x1a9 0x1 0xd135 0x90 +phy raw c45 0x1a9 0x1 0xd136 0x0 +phy raw c45 0x1a9 0x1 0xffde 7 +phy raw c45 0x1a9 0x1 0xd133 0x1000 +phy raw c45 0x1a9 0x1 0xd134 0x1e8 +phy raw c45 0x1a9 0x1 0xd135 0x90 +phy raw c45 0x1a9 0x1 0xd136 0x0 + +phy raw c45 0x1b1 0x1 0xffde 0 +phy raw c45 0x1b1 0x1 0xd133 0x1000 +phy raw c45 0x1b1 0x1 0xd134 0x1e8 +phy raw c45 0x1b1 0x1 0xd135 0x90 +phy raw c45 0x1b1 0x1 0xd136 0x0 +phy raw c45 0x1b1 0x1 0xffde 1 +phy raw c45 0x1b1 0x1 0xd133 0x1000 +phy raw c45 0x1b1 0x1 0xd134 0x1e8 +phy raw c45 0x1b1 0x1 0xd135 0x90 +phy raw c45 0x1b1 0x1 0xd136 0x0 +phy raw c45 0x1b1 0x1 0xffde 2 +phy raw c45 0x1b1 0x1 0xd133 0x1000 +phy raw c45 0x1b1 0x1 0xd134 0x1e8 +phy raw c45 0x1b1 0x1 0xd135 0x90 +phy raw c45 0x1b1 0x1 0xd136 0x0 +phy raw c45 0x1b1 0x1 0xffde 3 +phy raw c45 0x1b1 0x1 0xd133 0x1000 +phy raw c45 0x1b1 0x1 0xd134 0x1e8 +phy raw c45 0x1b1 0x1 0xd135 0x90 +phy raw c45 0x1b1 0x1 0xd136 0x0 +phy raw c45 0x1b1 0x1 0xffde 4 +phy raw c45 0x1b1 0x1 0xd133 0x1000 +phy raw c45 0x1b1 0x1 0xd134 0x1e8 +phy raw c45 0x1b1 0x1 0xd135 0x90 +phy raw c45 0x1b1 0x1 0xd136 0x0 +phy raw c45 0x1b1 0x1 0xffde 5 +phy raw c45 0x1b1 0x1 0xd133 0x1000 +phy raw c45 0x1b1 0x1 0xd134 0x1e8 +phy raw c45 0x1b1 0x1 0xd135 0x90 +phy raw c45 0x1b1 0x1 0xd136 0x0 +phy raw c45 0x1b1 0x1 0xffde 6 +phy raw c45 0x1b1 0x1 0xd133 0x1000 +phy raw c45 0x1b1 0x1 0xd134 0x1e8 +phy raw c45 0x1b1 0x1 0xd135 0x90 +phy raw c45 0x1b1 0x1 0xd136 0x0 +phy raw c45 0x1b1 0x1 0xffde 7 +phy raw c45 0x1b1 0x1 0xd133 0x1000 +phy raw c45 0x1b1 0x1 0xd134 0x1e8 +phy raw c45 0x1b1 0x1 0xd135 0x90 +phy raw c45 0x1b1 0x1 0xd136 0x0 + +phy raw c45 0x1c1 0x1 0xffde 0 +phy raw c45 0x1c1 0x1 0xd133 0x1000 +phy raw c45 0x1c1 0x1 0xd134 0x1e8 +phy raw c45 0x1c1 0x1 0xd135 0x90 +phy raw c45 0x1c1 0x1 0xd136 0x0 +phy raw c45 0x1c1 0x1 0xffde 1 +phy raw c45 0x1c1 0x1 0xd133 0x1000 +phy raw c45 0x1c1 0x1 0xd134 0x1e8 +phy raw c45 0x1c1 0x1 0xd135 0x90 +phy raw c45 0x1c1 0x1 0xd136 0x0 +phy raw c45 0x1c1 0x1 0xffde 2 +phy raw c45 0x1c1 0x1 0xd133 0x1000 +phy raw c45 0x1c1 0x1 0xd134 0x1e8 +phy raw c45 0x1c1 0x1 0xd135 0x90 +phy raw c45 0x1c1 0x1 0xd136 0x0 +phy raw c45 0x1c1 0x1 0xffde 3 +phy raw c45 0x1c1 0x1 0xd133 0x1000 +phy raw c45 0x1c1 0x1 0xd134 0x1e8 +phy raw c45 0x1c1 0x1 0xd135 0x90 +phy raw c45 0x1c1 0x1 0xd136 0x0 +phy raw c45 0x1c1 0x1 0xffde 4 +phy raw c45 0x1c1 0x1 0xd133 0x1000 +phy raw c45 0x1c1 0x1 0xd134 0x1e8 +phy raw c45 0x1c1 0x1 0xd135 0x90 +phy raw c45 0x1c1 0x1 0xd136 0x0 +phy raw c45 0x1c1 0x1 0xffde 5 +phy raw c45 0x1c1 0x1 0xd133 0x1000 +phy raw c45 0x1c1 0x1 0xd134 0x1e8 +phy raw c45 0x1c1 0x1 0xd135 0x90 +phy raw c45 0x1c1 0x1 0xd136 0x0 +phy raw c45 0x1c1 0x1 0xffde 6 +phy raw c45 0x1c1 0x1 0xd133 0x1000 +phy raw c45 0x1c1 0x1 0xd134 0x1e8 +phy raw c45 0x1c1 0x1 0xd135 0x90 +phy raw c45 0x1c1 0x1 0xd136 0x0 +phy raw c45 0x1c1 0x1 0xffde 7 +phy raw c45 0x1c1 0x1 0xd133 0x1000 +phy raw c45 0x1c1 0x1 0xd134 0x1e8 +phy raw c45 0x1c1 0x1 0xd135 0x90 +phy raw c45 0x1c1 0x1 0xd136 0x0 + +phy raw c45 0x1c9 0x1 0xffde 0 +phy raw c45 0x1c9 0x1 0xd133 0x1000 +phy raw c45 0x1c9 0x1 0xd134 0x1e8 +phy raw c45 0x1c9 0x1 0xd135 0x90 +phy raw c45 0x1c9 0x1 0xd136 0x0 +phy raw c45 0x1c9 0x1 0xffde 1 +phy raw c45 0x1c9 0x1 0xd133 0x1000 +phy raw c45 0x1c9 0x1 0xd134 0x1e8 +phy raw c45 0x1c9 0x1 0xd135 0x90 +phy raw c45 0x1c9 0x1 0xd136 0x0 +phy raw c45 0x1c9 0x1 0xffde 2 +phy raw c45 0x1c9 0x1 0xd133 0x1000 +phy raw c45 0x1c9 0x1 0xd134 0x1e8 +phy raw c45 0x1c9 0x1 0xd135 0x90 +phy raw c45 0x1c9 0x1 0xd136 0x0 +phy raw c45 0x1c9 0x1 0xffde 3 +phy raw c45 0x1c9 0x1 0xd133 0x1000 +phy raw c45 0x1c9 0x1 0xd134 0x1e8 +phy raw c45 0x1c9 0x1 0xd135 0x90 +phy raw c45 0x1c9 0x1 0xd136 0x0 +phy raw c45 0x1c9 0x1 0xffde 4 +phy raw c45 0x1c9 0x1 0xd133 0x1000 +phy raw c45 0x1c9 0x1 0xd134 0x1e8 +phy raw c45 0x1c9 0x1 0xd135 0x90 +phy raw c45 0x1c9 0x1 0xd136 0x0 +phy raw c45 0x1c9 0x1 0xffde 5 +phy raw c45 0x1c9 0x1 0xd133 0x1000 +phy raw c45 0x1c9 0x1 0xd134 0x1e8 +phy raw c45 0x1c9 0x1 0xd135 0x90 +phy raw c45 0x1c9 0x1 0xd136 0x0 +phy raw c45 0x1c9 0x1 0xffde 6 +phy raw c45 0x1c9 0x1 0xd133 0x1000 +phy raw c45 0x1c9 0x1 0xd134 0x1e8 +phy raw c45 0x1c9 0x1 0xd135 0x90 +phy raw c45 0x1c9 0x1 0xd136 0x0 +phy raw c45 0x1c9 0x1 0xffde 7 +phy raw c45 0x1c9 0x1 0xd133 0x1000 +phy raw c45 0x1c9 0x1 0xd134 0x1e8 +phy raw c45 0x1c9 0x1 0xd135 0x90 +phy raw c45 0x1c9 0x1 0xd136 0x0 + +phy raw c45 0x1d1 0x1 0xffde 0 +phy raw c45 0x1d1 0x1 0xd133 0x1000 +phy raw c45 0x1d1 0x1 0xd134 0x1e4 +phy raw c45 0x1d1 0x1 0xd135 0x8c +phy raw c45 0x1d1 0x1 0xd136 0x0 +phy raw c45 0x1d1 0x1 0xffde 1 +phy raw c45 0x1d1 0x1 0xd133 0x1000 +phy raw c45 0x1d1 0x1 0xd134 0x1e4 +phy raw c45 0x1d1 0x1 0xd135 0x8c +phy raw c45 0x1d1 0x1 0xd136 0x0 +phy raw c45 0x1d1 0x1 0xffde 2 +phy raw c45 0x1d1 0x1 0xd133 0x1000 +phy raw c45 0x1d1 0x1 0xd134 0x1e4 +phy raw c45 0x1d1 0x1 0xd135 0x8c +phy raw c45 0x1d1 0x1 0xd136 0x0 +phy raw c45 0x1d1 0x1 0xffde 3 +phy raw c45 0x1d1 0x1 0xd133 0x1000 +phy raw c45 0x1d1 0x1 0xd134 0x1e4 +phy raw c45 0x1d1 0x1 0xd135 0x8c +phy raw c45 0x1d1 0x1 0xd136 0x0 +phy raw c45 0x1d1 0x1 0xffde 4 +phy raw c45 0x1d1 0x1 0xd133 0x1000 +phy raw c45 0x1d1 0x1 0xd134 0x1e4 +phy raw c45 0x1d1 0x1 0xd135 0x8c +phy raw c45 0x1d1 0x1 0xd136 0x0 +phy raw c45 0x1d1 0x1 0xffde 5 +phy raw c45 0x1d1 0x1 0xd133 0x1000 +phy raw c45 0x1d1 0x1 0xd134 0x1e4 +phy raw c45 0x1d1 0x1 0xd135 0x8c +phy raw c45 0x1d1 0x1 0xd136 0x0 +phy raw c45 0x1d1 0x1 0xffde 6 +phy raw c45 0x1d1 0x1 0xd133 0x1000 +phy raw c45 0x1d1 0x1 0xd134 0x1e4 +phy raw c45 0x1d1 0x1 0xd135 0x8c +phy raw c45 0x1d1 0x1 0xd136 0x0 +phy raw c45 0x1d1 0x1 0xffde 7 +phy raw c45 0x1d1 0x1 0xd133 0x1000 +phy raw c45 0x1d1 0x1 0xd134 0x1e4 +phy raw c45 0x1d1 0x1 0xd135 0x8c +phy raw c45 0x1d1 0x1 0xd136 0x0 + +phy raw c45 0x1e1 0x1 0xffde 0 +phy raw c45 0x1e1 0x1 0xd133 0x1000 +phy raw c45 0x1e1 0x1 0xd134 0x1e8 +phy raw c45 0x1e1 0x1 0xd135 0x84 +phy raw c45 0x1e1 0x1 0xd136 0x1f4 +phy raw c45 0x1e1 0x1 0xffde 1 +phy raw c45 0x1e1 0x1 0xd133 0x1000 +phy raw c45 0x1e1 0x1 0xd134 0x1e8 +phy raw c45 0x1e1 0x1 0xd135 0x84 +phy raw c45 0x1e1 0x1 0xd136 0x1f4 +phy raw c45 0x1e1 0x1 0xffde 2 +phy raw c45 0x1e1 0x1 0xd133 0x1000 +phy raw c45 0x1e1 0x1 0xd134 0x1e8 +phy raw c45 0x1e1 0x1 0xd135 0x84 +phy raw c45 0x1e1 0x1 0xd136 0x1f4 +phy raw c45 0x1e1 0x1 0xffde 3 +phy raw c45 0x1e1 0x1 0xd133 0x1000 +phy raw c45 0x1e1 0x1 0xd134 0x1e8 +phy raw c45 0x1e1 0x1 0xd135 0x84 +phy raw c45 0x1e1 0x1 0xd136 0x1f4 +phy raw c45 0x1e1 0x1 0xffde 4 +phy raw c45 0x1e1 0x1 0xd133 0x1000 +phy raw c45 0x1e1 0x1 0xd134 0x1e8 +phy raw c45 0x1e1 0x1 0xd135 0x84 +phy raw c45 0x1e1 0x1 0xd136 0x1f4 +phy raw c45 0x1e1 0x1 0xffde 5 +phy raw c45 0x1e1 0x1 0xd133 0x1000 +phy raw c45 0x1e1 0x1 0xd134 0x1e8 +phy raw c45 0x1e1 0x1 0xd135 0x84 +phy raw c45 0x1e1 0x1 0xd136 0x1f4 +phy raw c45 0x1e1 0x1 0xffde 6 +phy raw c45 0x1e1 0x1 0xd133 0x1000 +phy raw c45 0x1e1 0x1 0xd134 0x1e8 +phy raw c45 0x1e1 0x1 0xd135 0x84 +phy raw c45 0x1e1 0x1 0xd136 0x1f4 +phy raw c45 0x1e1 0x1 0xffde 7 +phy raw c45 0x1e1 0x1 0xd133 0x1000 +phy raw c45 0x1e1 0x1 0xd134 0x1e8 +phy raw c45 0x1e1 0x1 0xd135 0x84 +phy raw c45 0x1e1 0x1 0xd136 0x1f4 + +phy raw c45 0x1e9 0x1 0xffde 0 +phy raw c45 0x1e9 0x1 0xd133 0x1000 +phy raw c45 0x1e9 0x1 0xd134 0x1e8 +phy raw c45 0x1e9 0x1 0xd135 0x84 +phy raw c45 0x1e9 0x1 0xd136 0x1f4 +phy raw c45 0x1e9 0x1 0xffde 1 +phy raw c45 0x1e9 0x1 0xd133 0x1000 +phy raw c45 0x1e9 0x1 0xd134 0x1e8 +phy raw c45 0x1e9 0x1 0xd135 0x84 +phy raw c45 0x1e9 0x1 0xd136 0x1f4 +phy raw c45 0x1e9 0x1 0xffde 2 +phy raw c45 0x1e9 0x1 0xd133 0x1000 +phy raw c45 0x1e9 0x1 0xd134 0x1e8 +phy raw c45 0x1e9 0x1 0xd135 0x84 +phy raw c45 0x1e9 0x1 0xd136 0x1f4 +phy raw c45 0x1e9 0x1 0xffde 3 +phy raw c45 0x1e9 0x1 0xd133 0x1000 +phy raw c45 0x1e9 0x1 0xd134 0x1e8 +phy raw c45 0x1e9 0x1 0xd135 0x84 +phy raw c45 0x1e9 0x1 0xd136 0x1f4 +phy raw c45 0x1e9 0x1 0xffde 4 +phy raw c45 0x1e9 0x1 0xd133 0x1000 +phy raw c45 0x1e9 0x1 0xd134 0x1e8 +phy raw c45 0x1e9 0x1 0xd135 0x84 +phy raw c45 0x1e9 0x1 0xd136 0x1f4 +phy raw c45 0x1e9 0x1 0xffde 5 +phy raw c45 0x1e9 0x1 0xd133 0x1000 +phy raw c45 0x1e9 0x1 0xd134 0x1e8 +phy raw c45 0x1e9 0x1 0xd135 0x84 +phy raw c45 0x1e9 0x1 0xd136 0x1f4 +phy raw c45 0x1e9 0x1 0xffde 6 +phy raw c45 0x1e9 0x1 0xd133 0x1000 +phy raw c45 0x1e9 0x1 0xd134 0x1e8 +phy raw c45 0x1e9 0x1 0xd135 0x84 +phy raw c45 0x1e9 0x1 0xd136 0x1f4 +phy raw c45 0x1e9 0x1 0xffde 7 +phy raw c45 0x1e9 0x1 0xd133 0x1000 +phy raw c45 0x1e9 0x1 0xd134 0x1e8 +phy raw c45 0x1e9 0x1 0xd135 0x84 +phy raw c45 0x1e9 0x1 0xd136 0x1f4 + +phy raw c45 0x1f1 0x1 0xffde 0 +phy raw c45 0x1f1 0x1 0xd133 0x1000 +phy raw c45 0x1f1 0x1 0xd134 0x1e8 +phy raw c45 0x1f1 0x1 0xd135 0x84 +phy raw c45 0x1f1 0x1 0xd136 0x1f4 +phy raw c45 0x1f1 0x1 0xffde 1 +phy raw c45 0x1f1 0x1 0xd133 0x1000 +phy raw c45 0x1f1 0x1 0xd134 0x1e8 +phy raw c45 0x1f1 0x1 0xd135 0x84 +phy raw c45 0x1f1 0x1 0xd136 0x1f4 +phy raw c45 0x1f1 0x1 0xffde 2 +phy raw c45 0x1f1 0x1 0xd133 0x1000 +phy raw c45 0x1f1 0x1 0xd134 0x1e8 +phy raw c45 0x1f1 0x1 0xd135 0x84 +phy raw c45 0x1f1 0x1 0xd136 0x1f4 +phy raw c45 0x1f1 0x1 0xffde 3 +phy raw c45 0x1f1 0x1 0xd133 0x1000 +phy raw c45 0x1f1 0x1 0xd134 0x1e8 +phy raw c45 0x1f1 0x1 0xd135 0x84 +phy raw c45 0x1f1 0x1 0xd136 0x1f4 +phy raw c45 0x1f1 0x1 0xffde 4 +phy raw c45 0x1f1 0x1 0xd133 0x1000 +phy raw c45 0x1f1 0x1 0xd134 0x1e8 +phy raw c45 0x1f1 0x1 0xd135 0x84 +phy raw c45 0x1f1 0x1 0xd136 0x1f4 +phy raw c45 0x1f1 0x1 0xffde 5 +phy raw c45 0x1f1 0x1 0xd133 0x1000 +phy raw c45 0x1f1 0x1 0xd134 0x1e8 +phy raw c45 0x1f1 0x1 0xd135 0x84 +phy raw c45 0x1f1 0x1 0xd136 0x1f4 +phy raw c45 0x1f1 0x1 0xffde 6 +phy raw c45 0x1f1 0x1 0xd133 0x1000 +phy raw c45 0x1f1 0x1 0xd134 0x1e8 +phy raw c45 0x1f1 0x1 0xd135 0x84 +phy raw c45 0x1f1 0x1 0xd136 0x1f4 +phy raw c45 0x1f1 0x1 0xffde 7 +phy raw c45 0x1f1 0x1 0xd133 0x1000 +phy raw c45 0x1f1 0x1 0xd134 0x1e8 +phy raw c45 0x1f1 0x1 0xd135 0x84 +phy raw c45 0x1f1 0x1 0xd136 0x1f4 + +phy raw c45 0x281 0x1 0xffde 0 +phy raw c45 0x281 0x1 0xd133 0x1000 +phy raw c45 0x281 0x1 0xd134 0x1e8 +phy raw c45 0x281 0x1 0xd135 0x90 +phy raw c45 0x281 0x1 0xd136 0x0 +phy raw c45 0x281 0x1 0xffde 1 +phy raw c45 0x281 0x1 0xd133 0x1000 +phy raw c45 0x281 0x1 0xd134 0x1e8 +phy raw c45 0x281 0x1 0xd135 0x90 +phy raw c45 0x281 0x1 0xd136 0x0 +phy raw c45 0x281 0x1 0xffde 2 +phy raw c45 0x281 0x1 0xd133 0x1000 +phy raw c45 0x281 0x1 0xd134 0x1e8 +phy raw c45 0x281 0x1 0xd135 0x90 +phy raw c45 0x281 0x1 0xd136 0x0 +phy raw c45 0x281 0x1 0xffde 3 +phy raw c45 0x281 0x1 0xd133 0x1000 +phy raw c45 0x281 0x1 0xd134 0x1e8 +phy raw c45 0x281 0x1 0xd135 0x90 +phy raw c45 0x281 0x1 0xd136 0x0 +phy raw c45 0x281 0x1 0xffde 4 +phy raw c45 0x281 0x1 0xd133 0x1000 +phy raw c45 0x281 0x1 0xd134 0x1e8 +phy raw c45 0x281 0x1 0xd135 0x90 +phy raw c45 0x281 0x1 0xd136 0x0 +phy raw c45 0x281 0x1 0xffde 5 +phy raw c45 0x281 0x1 0xd133 0x1000 +phy raw c45 0x281 0x1 0xd134 0x1e8 +phy raw c45 0x281 0x1 0xd135 0x90 +phy raw c45 0x281 0x1 0xd136 0x0 +phy raw c45 0x281 0x1 0xffde 6 +phy raw c45 0x281 0x1 0xd133 0x1000 +phy raw c45 0x281 0x1 0xd134 0x1e8 +phy raw c45 0x281 0x1 0xd135 0x90 +phy raw c45 0x281 0x1 0xd136 0x0 +phy raw c45 0x281 0x1 0xffde 7 +phy raw c45 0x281 0x1 0xd133 0x1000 +phy raw c45 0x281 0x1 0xd134 0x1e8 +phy raw c45 0x281 0x1 0xd135 0x90 +phy raw c45 0x281 0x1 0xd136 0x0 + +phy raw c45 0x289 0x1 0xffde 0 +phy raw c45 0x289 0x1 0xd133 0x1000 +phy raw c45 0x289 0x1 0xd134 0x1e8 +phy raw c45 0x289 0x1 0xd135 0x90 +phy raw c45 0x289 0x1 0xd136 0x0 +phy raw c45 0x289 0x1 0xffde 1 +phy raw c45 0x289 0x1 0xd133 0x1000 +phy raw c45 0x289 0x1 0xd134 0x1e8 +phy raw c45 0x289 0x1 0xd135 0x90 +phy raw c45 0x289 0x1 0xd136 0x0 +phy raw c45 0x289 0x1 0xffde 2 +phy raw c45 0x289 0x1 0xd133 0x1000 +phy raw c45 0x289 0x1 0xd134 0x1e8 +phy raw c45 0x289 0x1 0xd135 0x90 +phy raw c45 0x289 0x1 0xd136 0x0 +phy raw c45 0x289 0x1 0xffde 3 +phy raw c45 0x289 0x1 0xd133 0x1000 +phy raw c45 0x289 0x1 0xd134 0x1e8 +phy raw c45 0x289 0x1 0xd135 0x90 +phy raw c45 0x289 0x1 0xd136 0x0 +phy raw c45 0x289 0x1 0xffde 4 +phy raw c45 0x289 0x1 0xd133 0x1000 +phy raw c45 0x289 0x1 0xd134 0x1e8 +phy raw c45 0x289 0x1 0xd135 0x90 +phy raw c45 0x289 0x1 0xd136 0x0 +phy raw c45 0x289 0x1 0xffde 5 +phy raw c45 0x289 0x1 0xd133 0x1000 +phy raw c45 0x289 0x1 0xd134 0x1e8 +phy raw c45 0x289 0x1 0xd135 0x90 +phy raw c45 0x289 0x1 0xd136 0x0 +phy raw c45 0x289 0x1 0xffde 6 +phy raw c45 0x289 0x1 0xd133 0x1000 +phy raw c45 0x289 0x1 0xd134 0x1e8 +phy raw c45 0x289 0x1 0xd135 0x90 +phy raw c45 0x289 0x1 0xd136 0x0 +phy raw c45 0x289 0x1 0xffde 7 +phy raw c45 0x289 0x1 0xd133 0x1000 +phy raw c45 0x289 0x1 0xd134 0x1e8 +phy raw c45 0x289 0x1 0xd135 0x90 +phy raw c45 0x289 0x1 0xd136 0x0 + +phy raw c45 0x291 0x1 0xffde 0 +phy raw c45 0x291 0x1 0xd133 0x1004 +phy raw c45 0x291 0x1 0xd134 0x1e8 +phy raw c45 0x291 0x1 0xd135 0x7c +phy raw c45 0x291 0x1 0xd136 0x1f4 +phy raw c45 0x291 0x1 0xffde 1 +phy raw c45 0x291 0x1 0xd133 0x1004 +phy raw c45 0x291 0x1 0xd134 0x1e8 +phy raw c45 0x291 0x1 0xd135 0x7c +phy raw c45 0x291 0x1 0xd136 0x1f4 +phy raw c45 0x291 0x1 0xffde 2 +phy raw c45 0x291 0x1 0xd133 0x1004 +phy raw c45 0x291 0x1 0xd134 0x1e8 +phy raw c45 0x291 0x1 0xd135 0x7c +phy raw c45 0x291 0x1 0xd136 0x1f4 +phy raw c45 0x291 0x1 0xffde 3 +phy raw c45 0x291 0x1 0xd133 0x1004 +phy raw c45 0x291 0x1 0xd134 0x1e8 +phy raw c45 0x291 0x1 0xd135 0x7c +phy raw c45 0x291 0x1 0xd136 0x1f4 +phy raw c45 0x291 0x1 0xffde 4 +phy raw c45 0x291 0x1 0xd133 0x1004 +phy raw c45 0x291 0x1 0xd134 0x1e8 +phy raw c45 0x291 0x1 0xd135 0x7c +phy raw c45 0x291 0x1 0xd136 0x1f4 +phy raw c45 0x291 0x1 0xffde 5 +phy raw c45 0x291 0x1 0xd133 0x1004 +phy raw c45 0x291 0x1 0xd134 0x1e8 +phy raw c45 0x291 0x1 0xd135 0x7c +phy raw c45 0x291 0x1 0xd136 0x1f4 +phy raw c45 0x291 0x1 0xffde 6 +phy raw c45 0x291 0x1 0xd133 0x1004 +phy raw c45 0x291 0x1 0xd134 0x1e8 +phy raw c45 0x291 0x1 0xd135 0x7c +phy raw c45 0x291 0x1 0xd136 0x1f4 +phy raw c45 0x291 0x1 0xffde 7 +phy raw c45 0x291 0x1 0xd133 0x1004 +phy raw c45 0x291 0x1 0xd134 0x1e8 +phy raw c45 0x291 0x1 0xd135 0x7c +phy raw c45 0x291 0x1 0xd136 0x1f4 + +phy raw c45 0x2a1 0x1 0xffde 0 +phy raw c45 0x2a1 0x1 0xd133 0x1002 +phy raw c45 0x2a1 0x1 0xd134 0x1e4 +phy raw c45 0x2a1 0x1 0xd135 0x84 +phy raw c45 0x2a1 0x1 0xd136 0x1fc +phy raw c45 0x2a1 0x1 0xffde 1 +phy raw c45 0x2a1 0x1 0xd133 0x1002 +phy raw c45 0x2a1 0x1 0xd134 0x1e4 +phy raw c45 0x2a1 0x1 0xd135 0x84 +phy raw c45 0x2a1 0x1 0xd136 0x1fc +phy raw c45 0x2a1 0x1 0xffde 2 +phy raw c45 0x2a1 0x1 0xd133 0x1002 +phy raw c45 0x2a1 0x1 0xd134 0x1e4 +phy raw c45 0x2a1 0x1 0xd135 0x84 +phy raw c45 0x2a1 0x1 0xd136 0x1fc +phy raw c45 0x2a1 0x1 0xffde 3 +phy raw c45 0x2a1 0x1 0xd133 0x1002 +phy raw c45 0x2a1 0x1 0xd134 0x1e4 +phy raw c45 0x2a1 0x1 0xd135 0x84 +phy raw c45 0x2a1 0x1 0xd136 0x1fc +phy raw c45 0x2a1 0x1 0xffde 4 +phy raw c45 0x2a1 0x1 0xd133 0x1002 +phy raw c45 0x2a1 0x1 0xd134 0x1e4 +phy raw c45 0x2a1 0x1 0xd135 0x84 +phy raw c45 0x2a1 0x1 0xd136 0x1fc +phy raw c45 0x2a1 0x1 0xffde 5 +phy raw c45 0x2a1 0x1 0xd133 0x1002 +phy raw c45 0x2a1 0x1 0xd134 0x1e4 +phy raw c45 0x2a1 0x1 0xd135 0x84 +phy raw c45 0x2a1 0x1 0xd136 0x1fc +phy raw c45 0x2a1 0x1 0xffde 6 +phy raw c45 0x2a1 0x1 0xd133 0x1002 +phy raw c45 0x2a1 0x1 0xd134 0x1e4 +phy raw c45 0x2a1 0x1 0xd135 0x84 +phy raw c45 0x2a1 0x1 0xd136 0x1fc +phy raw c45 0x2a1 0x1 0xffde 7 +phy raw c45 0x2a1 0x1 0xd133 0x1002 +phy raw c45 0x2a1 0x1 0xd134 0x1e4 +phy raw c45 0x2a1 0x1 0xd135 0x84 +phy raw c45 0x2a1 0x1 0xd136 0x1fc + +phy raw c45 0x2a9 0x1 0xffde 0 +phy raw c45 0x2a9 0x1 0xd133 0x1002 +phy raw c45 0x2a9 0x1 0xd134 0x1e8 +phy raw c45 0x2a9 0x1 0xd135 0x80 +phy raw c45 0x2a9 0x1 0xd136 0x1f4 +phy raw c45 0x2a9 0x1 0xffde 1 +phy raw c45 0x2a9 0x1 0xd133 0x1002 +phy raw c45 0x2a9 0x1 0xd134 0x1e8 +phy raw c45 0x2a9 0x1 0xd135 0x80 +phy raw c45 0x2a9 0x1 0xd136 0x1f4 +phy raw c45 0x2a9 0x1 0xffde 2 +phy raw c45 0x2a9 0x1 0xd133 0x1002 +phy raw c45 0x2a9 0x1 0xd134 0x1e8 +phy raw c45 0x2a9 0x1 0xd135 0x80 +phy raw c45 0x2a9 0x1 0xd136 0x1f4 +phy raw c45 0x2a9 0x1 0xffde 3 +phy raw c45 0x2a9 0x1 0xd133 0x1002 +phy raw c45 0x2a9 0x1 0xd134 0x1e8 +phy raw c45 0x2a9 0x1 0xd135 0x80 +phy raw c45 0x2a9 0x1 0xd136 0x1f4 +phy raw c45 0x2a9 0x1 0xffde 4 +phy raw c45 0x2a9 0x1 0xd133 0x1002 +phy raw c45 0x2a9 0x1 0xd134 0x1e8 +phy raw c45 0x2a9 0x1 0xd135 0x80 +phy raw c45 0x2a9 0x1 0xd136 0x1f4 +phy raw c45 0x2a9 0x1 0xffde 5 +phy raw c45 0x2a9 0x1 0xd133 0x1002 +phy raw c45 0x2a9 0x1 0xd134 0x1e8 +phy raw c45 0x2a9 0x1 0xd135 0x80 +phy raw c45 0x2a9 0x1 0xd136 0x1f4 +phy raw c45 0x2a9 0x1 0xffde 6 +phy raw c45 0x2a9 0x1 0xd133 0x1002 +phy raw c45 0x2a9 0x1 0xd134 0x1e8 +phy raw c45 0x2a9 0x1 0xd135 0x80 +phy raw c45 0x2a9 0x1 0xd136 0x1f4 +phy raw c45 0x2a9 0x1 0xffde 7 +phy raw c45 0x2a9 0x1 0xd133 0x1002 +phy raw c45 0x2a9 0x1 0xd134 0x1e8 +phy raw c45 0x2a9 0x1 0xd135 0x80 +phy raw c45 0x2a9 0x1 0xd136 0x1f4 + +phy raw c45 0x2b1 0x1 0xffde 0 +phy raw c45 0x2b1 0x1 0xd133 0x1002 +phy raw c45 0x2b1 0x1 0xd134 0x1e8 +phy raw c45 0x2b1 0x1 0xd135 0x7c +phy raw c45 0x2b1 0x1 0xd136 0x1f0 +phy raw c45 0x2b1 0x1 0xffde 1 +phy raw c45 0x2b1 0x1 0xd133 0x1002 +phy raw c45 0x2b1 0x1 0xd134 0x1e8 +phy raw c45 0x2b1 0x1 0xd135 0x7c +phy raw c45 0x2b1 0x1 0xd136 0x1f0 +phy raw c45 0x2b1 0x1 0xffde 2 +phy raw c45 0x2b1 0x1 0xd133 0x1002 +phy raw c45 0x2b1 0x1 0xd134 0x1e8 +phy raw c45 0x2b1 0x1 0xd135 0x7c +phy raw c45 0x2b1 0x1 0xd136 0x1f0 +phy raw c45 0x2b1 0x1 0xffde 3 +phy raw c45 0x2b1 0x1 0xd133 0x1002 +phy raw c45 0x2b1 0x1 0xd134 0x1e8 +phy raw c45 0x2b1 0x1 0xd135 0x7c +phy raw c45 0x2b1 0x1 0xd136 0x1f0 +phy raw c45 0x2b1 0x1 0xffde 4 +phy raw c45 0x2b1 0x1 0xd133 0x1002 +phy raw c45 0x2b1 0x1 0xd134 0x1e8 +phy raw c45 0x2b1 0x1 0xd135 0x7c +phy raw c45 0x2b1 0x1 0xd136 0x1f0 +phy raw c45 0x2b1 0x1 0xffde 5 +phy raw c45 0x2b1 0x1 0xd133 0x1002 +phy raw c45 0x2b1 0x1 0xd134 0x1e8 +phy raw c45 0x2b1 0x1 0xd135 0x7c +phy raw c45 0x2b1 0x1 0xd136 0x1f0 +phy raw c45 0x2b1 0x1 0xffde 6 +phy raw c45 0x2b1 0x1 0xd133 0x1002 +phy raw c45 0x2b1 0x1 0xd134 0x1e8 +phy raw c45 0x2b1 0x1 0xd135 0x7c +phy raw c45 0x2b1 0x1 0xd136 0x1f0 +phy raw c45 0x2b1 0x1 0xffde 7 +phy raw c45 0x2b1 0x1 0xd133 0x1002 +phy raw c45 0x2b1 0x1 0xd134 0x1e8 +phy raw c45 0x2b1 0x1 0xd135 0x7c +phy raw c45 0x2b1 0x1 0xd136 0x1f0 + +phy raw c45 0x2c1 0x1 0xffde 0 +phy raw c45 0x2c1 0x1 0xd133 0x1004 +phy raw c45 0x2c1 0x1 0xd134 0x1e8 +phy raw c45 0x2c1 0x1 0xd135 0x78 +phy raw c45 0x2c1 0x1 0xd136 0x1f0 +phy raw c45 0x2c1 0x1 0xffde 1 +phy raw c45 0x2c1 0x1 0xd133 0x1004 +phy raw c45 0x2c1 0x1 0xd134 0x1e8 +phy raw c45 0x2c1 0x1 0xd135 0x78 +phy raw c45 0x2c1 0x1 0xd136 0x1f0 +phy raw c45 0x2c1 0x1 0xffde 2 +phy raw c45 0x2c1 0x1 0xd133 0x1004 +phy raw c45 0x2c1 0x1 0xd134 0x1e8 +phy raw c45 0x2c1 0x1 0xd135 0x78 +phy raw c45 0x2c1 0x1 0xd136 0x1f0 +phy raw c45 0x2c1 0x1 0xffde 3 +phy raw c45 0x2c1 0x1 0xd133 0x1004 +phy raw c45 0x2c1 0x1 0xd134 0x1e8 +phy raw c45 0x2c1 0x1 0xd135 0x78 +phy raw c45 0x2c1 0x1 0xd136 0x1f0 +phy raw c45 0x2c1 0x1 0xffde 4 +phy raw c45 0x2c1 0x1 0xd133 0x1004 +phy raw c45 0x2c1 0x1 0xd134 0x1e8 +phy raw c45 0x2c1 0x1 0xd135 0x78 +phy raw c45 0x2c1 0x1 0xd136 0x1f0 +phy raw c45 0x2c1 0x1 0xffde 5 +phy raw c45 0x2c1 0x1 0xd133 0x1004 +phy raw c45 0x2c1 0x1 0xd134 0x1e8 +phy raw c45 0x2c1 0x1 0xd135 0x78 +phy raw c45 0x2c1 0x1 0xd136 0x1f0 +phy raw c45 0x2c1 0x1 0xffde 6 +phy raw c45 0x2c1 0x1 0xd133 0x1004 +phy raw c45 0x2c1 0x1 0xd134 0x1e8 +phy raw c45 0x2c1 0x1 0xd135 0x78 +phy raw c45 0x2c1 0x1 0xd136 0x1f0 +phy raw c45 0x2c1 0x1 0xffde 7 +phy raw c45 0x2c1 0x1 0xd133 0x1004 +phy raw c45 0x2c1 0x1 0xd134 0x1e8 +phy raw c45 0x2c1 0x1 0xd135 0x78 +phy raw c45 0x2c1 0x1 0xd136 0x1f0 + +phy raw c45 0x2c9 0x1 0xffde 0 +phy raw c45 0x2c9 0x1 0xd133 0x1004 +phy raw c45 0x2c9 0x1 0xd134 0x1e4 +phy raw c45 0x2c9 0x1 0xd135 0x80 +phy raw c45 0x2c9 0x1 0xd136 0x1fc +phy raw c45 0x2c9 0x1 0xffde 1 +phy raw c45 0x2c9 0x1 0xd133 0x1004 +phy raw c45 0x2c9 0x1 0xd134 0x1e4 +phy raw c45 0x2c9 0x1 0xd135 0x80 +phy raw c45 0x2c9 0x1 0xd136 0x1fc +phy raw c45 0x2c9 0x1 0xffde 2 +phy raw c45 0x2c9 0x1 0xd133 0x1004 +phy raw c45 0x2c9 0x1 0xd134 0x1e4 +phy raw c45 0x2c9 0x1 0xd135 0x80 +phy raw c45 0x2c9 0x1 0xd136 0x1fc +phy raw c45 0x2c9 0x1 0xffde 3 +phy raw c45 0x2c9 0x1 0xd133 0x1004 +phy raw c45 0x2c9 0x1 0xd134 0x1e4 +phy raw c45 0x2c9 0x1 0xd135 0x80 +phy raw c45 0x2c9 0x1 0xd136 0x1fc +phy raw c45 0x2c9 0x1 0xffde 4 +phy raw c45 0x2c9 0x1 0xd133 0x1004 +phy raw c45 0x2c9 0x1 0xd134 0x1e4 +phy raw c45 0x2c9 0x1 0xd135 0x80 +phy raw c45 0x2c9 0x1 0xd136 0x1fc +phy raw c45 0x2c9 0x1 0xffde 5 +phy raw c45 0x2c9 0x1 0xd133 0x1004 +phy raw c45 0x2c9 0x1 0xd134 0x1e4 +phy raw c45 0x2c9 0x1 0xd135 0x80 +phy raw c45 0x2c9 0x1 0xd136 0x1fc +phy raw c45 0x2c9 0x1 0xffde 6 +phy raw c45 0x2c9 0x1 0xd133 0x1004 +phy raw c45 0x2c9 0x1 0xd134 0x1e4 +phy raw c45 0x2c9 0x1 0xd135 0x80 +phy raw c45 0x2c9 0x1 0xd136 0x1fc +phy raw c45 0x2c9 0x1 0xffde 7 +phy raw c45 0x2c9 0x1 0xd133 0x1004 +phy raw c45 0x2c9 0x1 0xd134 0x1e4 +phy raw c45 0x2c9 0x1 0xd135 0x80 +phy raw c45 0x2c9 0x1 0xd136 0x1fc diff --git a/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/sensors.conf b/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/sensors.conf new file mode 100755 index 0000000000..ffd5cf1d0a --- /dev/null +++ b/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/sensors.conf @@ -0,0 +1,13 @@ +# libsensors configuration file for snj60b0_320f +# ------------------------------------------------ + +#bus "i2c-1" "SMBus I801 adapter at f000" +#chip "goreme_power_cpld-*" +# label fan1 "Fan tray 1 front" +# label fan2 "Fan tray 2 front" +# label fan3 "Fan tray 3 front" +# label fan4 "Fan tray 4 front" +# label fan11 "Fan tray 1 rear" +# label fan12 "Fan tray 2 rear" +# label fan13 "Fan tray 3 rear" +# label fan14 "Fan tray 4 rear" diff --git a/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/thermal_policy.json b/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/thermal_policy.json new file mode 100755 index 0000000000..9514363845 --- /dev/null +++ b/device/alphanetworks/x86_64-alphanetworks_snj60b0_320f-r0/thermal_policy.json @@ -0,0 +1,93 @@ +{ + "thermal_control_algorithm": { + "run_at_boot_up": "True", + "fan_speed_when_suspend": "50" + }, + "info_types": [ + { + "type": "fan_info" + }, + { + "type": "thermal_info" + }, + { + "type": "chassis_info" + } + ], + "policies": [ + { + "name": "temp over high critical threshold", + "conditions": [ + { + "type": "thermal.over.high_critical_threshold" + } + ], + "actions": [ + { + "type": "switch.shutdown" + } + ] + }, + { + "name": "any fan absence", + "conditions": [ + { + "type": "fan.any.absence" + } + ], + "actions": [ + { + "type": "fan.all.set_speed_max" + } + ] + }, + { + "name": "any fan broken", + "conditions": [ + { + "type": "fan.any.fault" + } + ], + "actions": [ + { + "type": "fan.all.set_speed_max" + } + ] + }, + { + "name": "all fan presence", + "conditions": [ + { + "type": "fan.any.presence.change" + }, + { + "type": "fan.all.presence" + }, + { + "type": "fan.all.good" + } + ], + "actions": [ + { + "type": "fan.all.set_speed_default" + } + ] + }, + { + "name": "thermal recover", + "conditions": [ + { + "type": "fan.all.presence" + }, + { + "type": "fan.all.good" + } + ], + "actions": [ + { + "type": "thermal.temp_check_and_set_all_fan_speed" + } + ] + } + ] +} \ No newline at end of file diff --git a/platform/broadcom/one-image.mk b/platform/broadcom/one-image.mk old mode 100644 new mode 100755 index 86ac56b750..eeef34499a --- a/platform/broadcom/one-image.mk +++ b/platform/broadcom/one-image.mk @@ -54,6 +54,7 @@ $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(DELL_S6000_PLATFORM_MODULE) \ $(MITAC_LY1200_32X_PLATFORM_MODULE) \ $(ALPHANETWORKS_SNH60A0_320FV2_PLATFORM_MODULE) \ $(ALPHANETWORKS_SNH60B0_640F_PLATFORM_MODULE) \ + $(ALPHANETWORKS_SNJ60B0_320F_PLATFORM_MODULE) \ $(BRCM_XLR_GTS_PLATFORM_MODULE) \ $(DELTA_AG9032V2A_PLATFORM_MODULE) \ $(JUNIPER_QFX5210_PLATFORM_MODULE) \ diff --git a/platform/broadcom/platform-modules-alphanetworks.mk b/platform/broadcom/platform-modules-alphanetworks.mk old mode 100644 new mode 100755 index 13e5fc4ff9..689d5e42c8 --- a/platform/broadcom/platform-modules-alphanetworks.mk +++ b/platform/broadcom/platform-modules-alphanetworks.mk @@ -2,9 +2,11 @@ ALPHANETWORKS_SNH60A0_320FV2_PLATFORM_MODULE_VERSION = 1.0 ALPHANETWORKS_SNH60B0_640F_PLATFORM_MODULE_VERSION = 1.0 +ALPHANETWORKS_SNJ60B0_320F_PLATFORM_MODULE_VERSION = 1.0 export ALPHANETWORKS_SNH60A0_320FV2_PLATFORM_MODULE_VERSION export ALPHANETWORKS_SNH60B0_640F_PLATFORM_MODULE_VERSION +export ALPHANETWORKS_SNJ60B0_320F_PLATFORM_MODULE_VERSION ALPHANETWORKS_SNH60A0_320FV2_PLATFORM_MODULE = sonic-platform-alphanetworks-snh60a0-320fv2_$(ALPHANETWORKS_SNH60A0_320FV2_PLATFORM_MODULE_VERSION)_amd64.deb $(ALPHANETWORKS_SNH60A0_320FV2_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-alphanetworks @@ -16,5 +18,10 @@ ALPHANETWORKS_SNH60B0_640F_PLATFORM_MODULE = sonic-platform-alphanetworks-snh60b $(ALPHANETWORKS_SNH60B0_640F_PLATFORM_MODULE)_PLATFORM = x86_64-alphanetworks_snh60b0_640f-r0 $(eval $(call add_extra_package,$(ALPHANETWORKS_SNH60A0_320FV2_PLATFORM_MODULE),$(ALPHANETWORKS_SNH60B0_640F_PLATFORM_MODULE))) +ALPHANETWORKS_SNJ60B0_320F_PLATFORM_MODULE = sonic-platform-alphanetworks-snj60b0-320f_$(ALPHANETWORKS_SNJ60B0_320F_PLATFORM_MODULE_VERSION)_amd64.deb +$(ALPHANETWORKS_SNJ60B0_320F_PLATFORM_MODULE)_PLATFORM = x86_64-alphanetworks_snj60b0_320f-r0 +$(eval $(call add_extra_package,$(ALPHANETWORKS_SNH60A0_320FV2_PLATFORM_MODULE),$(ALPHANETWORKS_SNJ60B0_320F_PLATFORM_MODULE))) + +SONIC_STRETCH_DEBS += $(ALPHANETWORKS_SNH60A0_320FV2_PLATFORM_MODULE) diff --git a/platform/broadcom/sonic-platform-modules-alphanetworks/debian/changelog b/platform/broadcom/sonic-platform-modules-alphanetworks/debian/changelog old mode 100644 new mode 100755 index 2742b7c6a4..a0ac4888cb --- a/platform/broadcom/sonic-platform-modules-alphanetworks/debian/changelog +++ b/platform/broadcom/sonic-platform-modules-alphanetworks/debian/changelog @@ -1,6 +1,6 @@ sonic-alphanetworks-platform-modules (1.0) unstable; urgency=low - * Add support for SNH60A0-320FV2 and SNH60B0_640F. + * Add support for SNH60A0-320FV2 , SNH60B0_640F , SNJ60B0_320F. - -- Alphanetworks Tue, 19 Dec 2017 09:35:58 +0800 + -- Alphanetworks Tue, 16 June 2020 09:35:58 +0800 diff --git a/platform/broadcom/sonic-platform-modules-alphanetworks/debian/control b/platform/broadcom/sonic-platform-modules-alphanetworks/debian/control old mode 100644 new mode 100755 index d26493bfaa..fd296fd0ba --- a/platform/broadcom/sonic-platform-modules-alphanetworks/debian/control +++ b/platform/broadcom/sonic-platform-modules-alphanetworks/debian/control @@ -15,3 +15,7 @@ Architecture: amd64 Depends: linux-image-4.19.0-6-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp +Package: sonic-platform-alphanetworks-snj60b0-320f +Architecture: amd64 +Depends: linux-image-4.19.0-6-2-amd64-unsigned +Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/broadcom/sonic-platform-modules-alphanetworks/debian/rules b/platform/broadcom/sonic-platform-modules-alphanetworks/debian/rules index 0d1a588db6..a14baa8b2e 100755 --- a/platform/broadcom/sonic-platform-modules-alphanetworks/debian/rules +++ b/platform/broadcom/sonic-platform-modules-alphanetworks/debian/rules @@ -9,7 +9,7 @@ include /usr/share/dpkg/pkg-info.mk # Uncomment this to turn on verbose mode. -#export DH_VERBOSE=1 +export DH_VERBOSE=1 export INSTALL_MOD_DIR:=extra @@ -19,7 +19,7 @@ PACKAGE_PRE_NAME := sonic-platform-alphanetworks KVERSION ?= $(shell uname -r) KERNEL_SRC := /lib/modules/$(KVERSION) MOD_SRC_DIR:= $(shell pwd) -MODULE_DIRS:= snh60a0-320fv2 snh60b0-640f +MODULE_DIRS:= snh60a0-320fv2 snh60b0-640f snj60b0-320f MODULE_DIR := modules UTILS_DIR := utils SERVICE_DIR := service @@ -38,7 +38,10 @@ build: #make modules -C $(KERNEL_SRC)/build M=$(MODULE_SRC) (for mod in $(MODULE_DIRS); do \ make modules -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules; \ - $(PYTHON) $${mod}/setup.py build; \ + cd $(MOD_SRC_DIR)/$${mod}; \ + $(PYTHON) setup.py build; \ + $(PYTHON) setup.py bdist_wheel -d $(MOD_SRC_DIR)/$${mod}/utils; \ + cd $(MOD_SRC_DIR); \ done) binary: binary-arch binary-indep @@ -59,13 +62,18 @@ binary-indep: # Custom package commands (for mod in $(MODULE_DIRS); do \ - dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod}/$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ - dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod}/usr/local/bin; \ - dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod}/lib/systemd/system; \ + dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod} $(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ + dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod} usr/local/bin; \ + platform_name=`echo $${mod} | sed "s/-/_/g"`; \ + dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod} usr/share/sonic/device/x86_64-alphanetworks_$${platform_name}-r0; \ + dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod} lib/systemd/system; \ cp $(MOD_SRC_DIR)/$${mod}/$(MODULE_DIR)/*.ko debian/$(PACKAGE_PRE_NAME)-$${mod}/$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ - cp $(MOD_SRC_DIR)/$${mod}/$(UTILS_DIR)/* debian/$(PACKAGE_PRE_NAME)-$${mod}/usr/local/bin/; \ + cp $(MOD_SRC_DIR)/$${mod}/$(UTILS_DIR)/*.py debian/$(PACKAGE_PRE_NAME)-$${mod}/usr/local/bin/; \ + cp $(MOD_SRC_DIR)/$${mod}/$(UTILS_DIR)/*.whl debian/$(PACKAGE_PRE_NAME)-$${mod}/usr/share/sonic/device/x86_64-alphanetworks_$${platform_name}-r0; \ cp $(MOD_SRC_DIR)/$${mod}/$(SERVICE_DIR)/*.service debian/$(PACKAGE_PRE_NAME)-$${mod}/lib/systemd/system/; \ - $(PYTHON) $${mod}/setup.py install --root=$(MOD_SRC_DIR)/debian/$(PACKAGE_PRE_NAME)-$${mod} --install-layout=deb; \ + cd $(MOD_SRC_DIR)/$${mod}; \ + $(PYTHON) setup.py install --root=$(MOD_SRC_DIR)/debian/$(PACKAGE_PRE_NAME)-$${mod} --install-layout=deb; \ + cd $(MOD_SRC_DIR); \ done) # Resuming debhelper scripts dh_testroot diff --git a/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/classes/__init__.py b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/classes/__init__.py new file mode 100755 index 0000000000..e69de29bb2 diff --git a/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/modules/Makefile b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/modules/Makefile new file mode 100755 index 0000000000..86f32fee02 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/modules/Makefile @@ -0,0 +1,8 @@ +# obj-m:=accton_as7712_32x_fan.o accton_as7712_32x_sfp.o leds-accton_as7712_32x.o \ +# goreme_system_cpld.o ym2651y.o optoe.o + +obj-m:=snj60b0-320f_sfp.o snj60b0-320f_fpga.o snj60b0-320f_onie_eeprom.o yesm1300am.o + + +# obj-m:=accton_as7712_32x_fan.o accton_as7712_32x_sfp.o leds-accton_as7712_32x.o \ +# accton_as7712_32x_psu.o accton_i2c_cpld.o ym2651y.o optoe.o diff --git a/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/modules/snj60b0-320f_fpga.c b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/modules/snj60b0-320f_fpga.c new file mode 100755 index 0000000000..8167791d8f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/modules/snj60b0-320f_fpga.c @@ -0,0 +1,955 @@ +/* + * A hwmon driver for the alphanetworks_snj60b0_320f_fpga + * + * Copyright (C) 2019 Alphanetworks Technology Corporation. + * Robin Chen + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * see + * + * Copyright 2006 Stefan Roese , DENX Software Engineering + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define DRIVER_NAME "snj60b0_fpga" +#define PSU1_STATUS_REG 0x2 +#define PSU2_STATUS_REG 0x3 +#define FAN_PWM_REG 0x18 + +#define PSU_PRESENT_BIT 0x10 +#define PSU_POWER_BIT 0x20 +#define FAN_DIRECTION_BIT 0x1 +#define FAN_PRESENT_BIT 0x2 +#define FPGA_REVISION_BIT 0xF + +#define FPGA_REVISION_REG 0x0 +#define SYS_LED_REG 0x2D +#define SYS2_LED_REG 0x2E +#define FAN12_LED_REG 0x30 +#define FAN34_LED_REG 0x31 +#define FAN56_LED_REG 0x32 + +#define FAN1_STATUS_REG 0x5 +#define FAN2_STATUS_REG 0x6 +#define FAN3_STATUS_REG 0x7 +#define FAN4_STATUS_REG 0x8 +#define FAN5_STATUS_REG 0x9 +#define FAN6_STATUS_REG 0xA + +#define SYS_RESET1_REG 0x1C +#define SYS_RESET2_REG 0x1D +#define SYS_RESET3_REG 0x1E +//#define SWI_CTRL_REG 0x4 + +#define SYS_LOCATOR_LED_BITS 0x07 +#define SYS_PWR_LED_BITS 0x38 +#define PORT_LED_DISABLE_BITS 0x40 +#define SYS_STATUS_LED_BITS 0x07 +#define SYS_FAN_LED_BITS 0x38 +#define FAN135_LED_BITS 0x07 +#define FAN246_LED_BITS 0x38 +#define REST_BUTTON_BITS 0x0 + +#define SFP_TX_FAULT_REG 0x25 +#define SFP_TX_FAULT_MASK_REG 0x26 +#define SFP_TX_DISABLE_REG 0x27 +#define SFP_PRESENT_REG 0x28 +#define SFP_PRESENT_MASK_REG 0x29 +#define SFP_RX_LOSS_REG 0x2A +#define SFP_RX_LOSS_MASK_REG 0x2B +//#define SWI_CTRL_REG 0x34 + + + + +static ssize_t psu_show_status(struct device *dev, struct device_attribute *attr, char *buf); +static ssize_t fan_pwm_show(struct device *dev, struct device_attribute *attr, char *buf); +static ssize_t set_fan_pwm(struct device *dev, struct device_attribute *attr, const char *buf, size_t count); +static ssize_t fpga_version_show(struct device *dev, struct device_attribute *attr, char *buf); + +static ssize_t fan_show_status(struct device *dev, struct device_attribute *attr, char *buf); +static ssize_t fan_show_status_reg(struct device *dev, struct device_attribute *attr, char *buf); + +static ssize_t sys_sfp_read(struct device *dev, struct device_attribute *attr, char *buf); +static ssize_t sys_sfp_write(struct device *dev, struct device_attribute *attr, const char *buf, size_t count); + +static ssize_t sys_led_read(struct device *dev, struct device_attribute *attr, char *buf); +static ssize_t sys_led_write(struct device *dev, struct device_attribute *attr, const char *buf, size_t count); + +static LIST_HEAD(fpga_client_list); +static struct mutex list_lock; + +struct fpga_client_node { + struct i2c_client *client; + struct list_head list; +}; + +/* Addresses scanned for alphanetworks_snj60b0_320f_fpga */ +static const unsigned short normal_i2c[] = { 0x5E, I2C_CLIENT_END }; + +struct alphanetworks_snj60b0_320f_pwr_fpga_data { + struct device *hwmon_dev; + struct mutex update_lock; + char model_name[9]; /* Model name, read from eeprom */ +}; + + +enum sysfs_fpga_attributes { + PSU1_PRESENT, + PSU2_PRESENT, + PSU1_POWER_GOOD, + PSU2_POWER_GOOD, + FAN_PWM, + FAN1_PRESENT=0x05, + FAN2_PRESENT, + FAN3_PRESENT, + FAN4_PRESENT, + FAN5_PRESENT, + FAN6_PRESENT, + FAN1_FRONT_SPEED_RPM=0x0b, + FAN1_REAR_SPEED_RPM, + FAN2_FRONT_SPEED_RPM, + FAN2_REAR_SPEED_RPM, + FAN3_FRONT_SPEED_RPM, + FAN3_REAR_SPEED_RPM, + FAN4_FRONT_SPEED_RPM, + FAN4_REAR_SPEED_RPM, + FAN5_FRONT_SPEED_RPM, + FAN5_REAR_SPEED_RPM, + FAN6_FRONT_SPEED_RPM, + FAN6_REAR_SPEED_RPM, + FAN1_FAULT, + FAN2_FAULT, + FAN3_FAULT, + FAN4_FAULT, + FAN5_FAULT, + FAN6_FAULT, + SYS_STATUS, + SYS_PWR, + SYS_FAN, + SYS_LOCATOR, + SFP_TX_FAULT, + SFP_TX_FAULT_MASK, + SFP_TX_DISABLE, + SFP_PRESENT, + SFP_PRESENT_MASK, + SFP_RX_LOSS, + SFP_RX_LOSS_MASK, + FAN1_LED, + FAN2_LED, + FAN3_LED, + FAN4_LED, + FAN5_LED, + FAN6_LED, + SYS_RESET1, + SYS_RESET2, + SYS_RESET3, + PORT_LED_DISABLE, + FAN1_DIRECTION, + FAN2_DIRECTION, + FAN3_DIRECTION, + FAN4_DIRECTION, + FAN5_DIRECTION, + FAN6_DIRECTION, + FPGA_REVISION, +}; + + + + + + +static SENSOR_DEVICE_ATTR(psu1_present, S_IRUGO, psu_show_status, NULL, PSU1_PRESENT); +static SENSOR_DEVICE_ATTR(psu2_present, S_IRUGO, psu_show_status, NULL, PSU2_PRESENT); +static SENSOR_DEVICE_ATTR(psu1_power_good, S_IRUGO, psu_show_status, NULL, PSU1_POWER_GOOD); +static SENSOR_DEVICE_ATTR(psu2_power_good, S_IRUGO, psu_show_status, NULL, PSU2_POWER_GOOD); +static SENSOR_DEVICE_ATTR(fan_pwm, (0660), fan_pwm_show, set_fan_pwm, FAN_PWM); +static SENSOR_DEVICE_ATTR(fpga_revision, (0660), fpga_version_show, NULL, FPGA_REVISION); +static SENSOR_DEVICE_ATTR(fan1_present, S_IRUGO, fan_show_status_reg, NULL, FAN1_PRESENT); +static SENSOR_DEVICE_ATTR(fan2_present, S_IRUGO, fan_show_status_reg, NULL, FAN2_PRESENT); +static SENSOR_DEVICE_ATTR(fan3_present, S_IRUGO, fan_show_status_reg, NULL, FAN3_PRESENT); +static SENSOR_DEVICE_ATTR(fan4_present, S_IRUGO, fan_show_status_reg, NULL, FAN4_PRESENT); +static SENSOR_DEVICE_ATTR(fan5_present, S_IRUGO, fan_show_status_reg, NULL, FAN5_PRESENT); +static SENSOR_DEVICE_ATTR(fan6_present, S_IRUGO, fan_show_status_reg, NULL, FAN6_PRESENT); +static SENSOR_DEVICE_ATTR(fan1_direction, S_IRUGO, fan_show_status_reg, NULL, FAN1_DIRECTION); +static SENSOR_DEVICE_ATTR(fan2_direction, S_IRUGO, fan_show_status_reg, NULL, FAN2_DIRECTION); +static SENSOR_DEVICE_ATTR(fan3_direction, S_IRUGO, fan_show_status_reg, NULL, FAN3_DIRECTION); +static SENSOR_DEVICE_ATTR(fan4_direction, S_IRUGO, fan_show_status_reg, NULL, FAN4_DIRECTION); +static SENSOR_DEVICE_ATTR(fan5_direction, S_IRUGO, fan_show_status_reg, NULL, FAN5_DIRECTION); +static SENSOR_DEVICE_ATTR(fan6_direction, S_IRUGO, fan_show_status_reg, NULL, FAN6_DIRECTION); +static SENSOR_DEVICE_ATTR(fan1_front_speed_rpm, S_IRUGO, fan_show_status, NULL, FAN1_FRONT_SPEED_RPM); +static SENSOR_DEVICE_ATTR(fan2_front_speed_rpm, S_IRUGO, fan_show_status, NULL, FAN2_FRONT_SPEED_RPM); +static SENSOR_DEVICE_ATTR(fan3_front_speed_rpm, S_IRUGO, fan_show_status, NULL, FAN3_FRONT_SPEED_RPM); +static SENSOR_DEVICE_ATTR(fan4_front_speed_rpm, S_IRUGO, fan_show_status, NULL, FAN4_FRONT_SPEED_RPM); +static SENSOR_DEVICE_ATTR(fan5_front_speed_rpm, S_IRUGO, fan_show_status, NULL, FAN5_FRONT_SPEED_RPM); +static SENSOR_DEVICE_ATTR(fan6_front_speed_rpm, S_IRUGO, fan_show_status, NULL, FAN6_FRONT_SPEED_RPM); +static SENSOR_DEVICE_ATTR(fan1_rear_speed_rpm, S_IRUGO, fan_show_status, NULL, FAN1_REAR_SPEED_RPM); +static SENSOR_DEVICE_ATTR(fan2_rear_speed_rpm, S_IRUGO, fan_show_status, NULL, FAN2_REAR_SPEED_RPM); +static SENSOR_DEVICE_ATTR(fan3_rear_speed_rpm, S_IRUGO, fan_show_status, NULL, FAN3_REAR_SPEED_RPM); +static SENSOR_DEVICE_ATTR(fan4_rear_speed_rpm, S_IRUGO, fan_show_status, NULL, FAN4_REAR_SPEED_RPM); +static SENSOR_DEVICE_ATTR(fan5_rear_speed_rpm, S_IRUGO, fan_show_status, NULL, FAN5_REAR_SPEED_RPM); +static SENSOR_DEVICE_ATTR(fan6_rear_speed_rpm, S_IRUGO, fan_show_status, NULL, FAN6_REAR_SPEED_RPM); + +static SENSOR_DEVICE_ATTR(fan1_fault, S_IRUGO, fan_show_status, NULL, FAN1_FAULT); static SENSOR_DEVICE_ATTR(fan11_fault, S_IRUGO, fan_show_status, NULL, FAN1_FAULT); +static SENSOR_DEVICE_ATTR(fan2_fault, S_IRUGO, fan_show_status, NULL, FAN2_FAULT); static SENSOR_DEVICE_ATTR(fan12_fault, S_IRUGO, fan_show_status, NULL, FAN2_FAULT); +static SENSOR_DEVICE_ATTR(fan3_fault, S_IRUGO, fan_show_status, NULL, FAN3_FAULT); static SENSOR_DEVICE_ATTR(fan13_fault, S_IRUGO, fan_show_status, NULL, FAN3_FAULT); +static SENSOR_DEVICE_ATTR(fan4_fault, S_IRUGO, fan_show_status, NULL, FAN4_FAULT); static SENSOR_DEVICE_ATTR(fan14_fault, S_IRUGO, fan_show_status, NULL, FAN4_FAULT); +static SENSOR_DEVICE_ATTR(fan5_fault, S_IRUGO, fan_show_status, NULL, FAN5_FAULT); static SENSOR_DEVICE_ATTR(fan15_fault, S_IRUGO, fan_show_status, NULL, FAN5_FAULT); +static SENSOR_DEVICE_ATTR(fan6_fault, S_IRUGO, fan_show_status, NULL, FAN6_FAULT); static SENSOR_DEVICE_ATTR(fan16_fault, S_IRUGO, fan_show_status, NULL, FAN6_FAULT); +static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, fan_show_status, NULL, FAN1_FRONT_SPEED_RPM); static SENSOR_DEVICE_ATTR(fan11_input, S_IRUGO, fan_show_status, NULL, FAN1_REAR_SPEED_RPM); +static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, fan_show_status, NULL, FAN2_FRONT_SPEED_RPM); static SENSOR_DEVICE_ATTR(fan12_input, S_IRUGO, fan_show_status, NULL, FAN2_REAR_SPEED_RPM); +static SENSOR_DEVICE_ATTR(fan3_input, S_IRUGO, fan_show_status, NULL, FAN3_FRONT_SPEED_RPM); static SENSOR_DEVICE_ATTR(fan13_input, S_IRUGO, fan_show_status, NULL, FAN3_REAR_SPEED_RPM); +static SENSOR_DEVICE_ATTR(fan4_input, S_IRUGO, fan_show_status, NULL, FAN4_FRONT_SPEED_RPM); static SENSOR_DEVICE_ATTR(fan14_input, S_IRUGO, fan_show_status, NULL, FAN4_REAR_SPEED_RPM); +static SENSOR_DEVICE_ATTR(fan5_input, S_IRUGO, fan_show_status, NULL, FAN5_FRONT_SPEED_RPM); static SENSOR_DEVICE_ATTR(fan15_input, S_IRUGO, fan_show_status, NULL, FAN5_REAR_SPEED_RPM); +static SENSOR_DEVICE_ATTR(fan6_input, S_IRUGO, fan_show_status, NULL, FAN6_FRONT_SPEED_RPM); static SENSOR_DEVICE_ATTR(fan16_input, S_IRUGO, fan_show_status, NULL, FAN6_REAR_SPEED_RPM); + +static SENSOR_DEVICE_ATTR(sys_status, (0600), sys_led_read, sys_led_write, SYS_STATUS); +static SENSOR_DEVICE_ATTR(port_led_disable, (0660), sys_led_read, sys_led_write, PORT_LED_DISABLE); +static SENSOR_DEVICE_ATTR(sys_pwr, (0660), sys_led_read, sys_led_write, SYS_PWR); +static SENSOR_DEVICE_ATTR(sys_locator, (0660), sys_led_read, sys_led_write, SYS_LOCATOR); +static SENSOR_DEVICE_ATTR(fan1_led, (0660), sys_led_read, sys_led_write, FAN1_LED); +static SENSOR_DEVICE_ATTR(fan2_led, (0660), sys_led_read, sys_led_write, FAN2_LED); +static SENSOR_DEVICE_ATTR(fan3_led, (0660), sys_led_read, sys_led_write, FAN3_LED); +static SENSOR_DEVICE_ATTR(fan4_led, (0660), sys_led_read, sys_led_write, FAN4_LED); +static SENSOR_DEVICE_ATTR(fan5_led, (0660), sys_led_read, sys_led_write, FAN5_LED); +static SENSOR_DEVICE_ATTR(fan6_led, (0660), sys_led_read, sys_led_write, FAN6_LED); +static SENSOR_DEVICE_ATTR(sys_reset1, (0660), sys_led_read, sys_led_write, SYS_RESET1); +static SENSOR_DEVICE_ATTR(sys_reset2, (0660), sys_led_read, sys_led_write, SYS_RESET2); +static SENSOR_DEVICE_ATTR(sys_reset3, (0660), sys_led_read, sys_led_write, SYS_RESET3); + +static SENSOR_DEVICE_ATTR(sfp_tx_fault, (0660), sys_sfp_read, sys_sfp_write, SFP_TX_FAULT); +static SENSOR_DEVICE_ATTR(sfp_tx_fault_mask, (0660), sys_sfp_read, sys_sfp_write, SFP_TX_FAULT_MASK); +static SENSOR_DEVICE_ATTR(sfp_tx_disable, (0660), sys_sfp_read, sys_sfp_write, SFP_TX_DISABLE); +static SENSOR_DEVICE_ATTR(sfp_present, (0660), sys_sfp_read, sys_sfp_write, SFP_PRESENT); +static SENSOR_DEVICE_ATTR(sfp_present_mask, (0660), sys_sfp_read, sys_sfp_write, SFP_PRESENT_MASK); +static SENSOR_DEVICE_ATTR(sfp_rx_loss, (0660), sys_sfp_read, sys_sfp_write, SFP_RX_LOSS); +static SENSOR_DEVICE_ATTR(sfp_rx_loss_mask, (0660), sys_sfp_read, sys_sfp_write, SFP_RX_LOSS_MASK); + + +static struct attribute *alphanetworks_snj60b0_320f_fpga_attributes[] = { + &sensor_dev_attr_psu1_present.dev_attr.attr, + &sensor_dev_attr_psu2_present.dev_attr.attr, + &sensor_dev_attr_psu1_power_good.dev_attr.attr, + &sensor_dev_attr_psu2_power_good.dev_attr.attr, + &sensor_dev_attr_fan_pwm.dev_attr.attr, + &sensor_dev_attr_fan1_present.dev_attr.attr, + &sensor_dev_attr_fan2_present.dev_attr.attr, + &sensor_dev_attr_fan3_present.dev_attr.attr, + &sensor_dev_attr_fan4_present.dev_attr.attr, + &sensor_dev_attr_fan5_present.dev_attr.attr, + &sensor_dev_attr_fan6_present.dev_attr.attr, + &sensor_dev_attr_fan1_front_speed_rpm.dev_attr.attr, + &sensor_dev_attr_fan2_front_speed_rpm.dev_attr.attr, + &sensor_dev_attr_fan3_front_speed_rpm.dev_attr.attr, + &sensor_dev_attr_fan4_front_speed_rpm.dev_attr.attr, + &sensor_dev_attr_fan5_front_speed_rpm.dev_attr.attr, + &sensor_dev_attr_fan6_front_speed_rpm.dev_attr.attr, + &sensor_dev_attr_fan1_rear_speed_rpm.dev_attr.attr, + &sensor_dev_attr_fan2_rear_speed_rpm.dev_attr.attr, + &sensor_dev_attr_fan3_rear_speed_rpm.dev_attr.attr, + &sensor_dev_attr_fan4_rear_speed_rpm.dev_attr.attr, + &sensor_dev_attr_fan5_rear_speed_rpm.dev_attr.attr, + &sensor_dev_attr_fan6_rear_speed_rpm.dev_attr.attr, + &sensor_dev_attr_fan1_fault.dev_attr.attr, &sensor_dev_attr_fan11_fault.dev_attr.attr, + &sensor_dev_attr_fan2_fault.dev_attr.attr, &sensor_dev_attr_fan12_fault.dev_attr.attr, + &sensor_dev_attr_fan3_fault.dev_attr.attr, &sensor_dev_attr_fan13_fault.dev_attr.attr, + &sensor_dev_attr_fan4_fault.dev_attr.attr, &sensor_dev_attr_fan14_fault.dev_attr.attr, + &sensor_dev_attr_fan5_fault.dev_attr.attr, &sensor_dev_attr_fan15_fault.dev_attr.attr, + &sensor_dev_attr_fan6_fault.dev_attr.attr, &sensor_dev_attr_fan16_fault.dev_attr.attr, + &sensor_dev_attr_fan1_input.dev_attr.attr, &sensor_dev_attr_fan11_input.dev_attr.attr, + &sensor_dev_attr_fan2_input.dev_attr.attr, &sensor_dev_attr_fan12_input.dev_attr.attr, + &sensor_dev_attr_fan3_input.dev_attr.attr, &sensor_dev_attr_fan13_input.dev_attr.attr, + &sensor_dev_attr_fan4_input.dev_attr.attr, &sensor_dev_attr_fan14_input.dev_attr.attr, + &sensor_dev_attr_fan5_input.dev_attr.attr, &sensor_dev_attr_fan15_input.dev_attr.attr, + &sensor_dev_attr_fan6_input.dev_attr.attr, &sensor_dev_attr_fan16_input.dev_attr.attr, + &sensor_dev_attr_sys_status.dev_attr.attr, + &sensor_dev_attr_sys_pwr.dev_attr.attr, + &sensor_dev_attr_fan1_led.dev_attr.attr, + &sensor_dev_attr_fan2_led.dev_attr.attr, + &sensor_dev_attr_fan3_led.dev_attr.attr, + &sensor_dev_attr_fan4_led.dev_attr.attr, + &sensor_dev_attr_fan5_led.dev_attr.attr, + &sensor_dev_attr_fan6_led.dev_attr.attr, + &sensor_dev_attr_sys_reset1.dev_attr.attr, + &sensor_dev_attr_sys_reset2.dev_attr.attr, + &sensor_dev_attr_sys_reset3.dev_attr.attr, + &sensor_dev_attr_sfp_tx_fault.dev_attr.attr, + &sensor_dev_attr_sfp_tx_fault_mask.dev_attr.attr, + &sensor_dev_attr_sfp_tx_disable.dev_attr.attr, + &sensor_dev_attr_sfp_present.dev_attr.attr, + &sensor_dev_attr_sfp_present_mask.dev_attr.attr, + &sensor_dev_attr_sfp_rx_loss.dev_attr.attr, + &sensor_dev_attr_sfp_rx_loss_mask.dev_attr.attr, + &sensor_dev_attr_sys_locator.dev_attr.attr, + &sensor_dev_attr_port_led_disable.dev_attr.attr, + &sensor_dev_attr_fan1_direction.dev_attr.attr, + &sensor_dev_attr_fan2_direction.dev_attr.attr, + &sensor_dev_attr_fan3_direction.dev_attr.attr, + &sensor_dev_attr_fan4_direction.dev_attr.attr, + &sensor_dev_attr_fan5_direction.dev_attr.attr, + &sensor_dev_attr_fan6_direction.dev_attr.attr, + &sensor_dev_attr_fpga_revision.dev_attr.attr, + NULL +}; + +static const struct attribute_group alphanetworks_snj60b0_320f_fpga_group = { + .attrs = alphanetworks_snj60b0_320f_fpga_attributes, +}; + + +static ssize_t psu_show_status(struct device *dev, struct device_attribute *attr, char *buf) +{ + int val = 0, res = 0; + u8 command; + struct i2c_client *client = to_i2c_client(dev); + struct sensor_device_attribute *sda = to_sensor_dev_attr(attr); + + switch(sda->index) { + case PSU1_PRESENT: + case PSU1_POWER_GOOD: + command = PSU1_STATUS_REG; + break; + case PSU2_PRESENT: + case PSU2_POWER_GOOD: + command = PSU2_STATUS_REG; + break; + } + + val = i2c_smbus_read_byte_data(client, command); + if (val < 0) { + dev_dbg(&client->dev, "fpga(0x%x) reg(0x1) err %d\n", client->addr, val); + } + + switch(sda->index) { + case PSU1_PRESENT: + case PSU2_PRESENT: + res = (val & PSU_PRESENT_BIT ? 0 : 1 ); + break; + case PSU1_POWER_GOOD: + case PSU2_POWER_GOOD: + res = (val & PSU_POWER_BIT ? 1 : 0 ); + break; + } + + return sprintf(buf, "%d\n", res); +} + +static ssize_t fan_pwm_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + int val = 0; + struct i2c_client *client = to_i2c_client(dev); + + val = i2c_smbus_read_byte_data(client, FAN_PWM_REG); + + if (val < 0) { + dev_dbg(&client->dev, "fpga(0x%x) reg(0x1) err %d\n", client->addr, val); + } + + return sprintf(buf, "%d", val); +} + +static ssize_t set_fan_pwm(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + int error, value; + + error = kstrtoint(buf, 10, &value); + if (error) + return error; + + if (value < 0 || value > 0xFF) + return -EINVAL; + + i2c_smbus_write_byte_data(client, FAN_PWM_REG, value); + + return count; +} + +static ssize_t fpga_version_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + int val = 0; + struct i2c_client *client = to_i2c_client(dev); + + val = i2c_smbus_read_byte_data(client, FPGA_REVISION_REG); + + if (val < 0) { + dev_dbg(&client->dev, "fpga(0x%x) reg(0x1) err %d\n", client->addr, val); + } + + return sprintf(buf, "%d\n", (val & FPGA_REVISION_BIT)); +} + +static ssize_t fan_show_status(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct sensor_device_attribute *sda = to_sensor_dev_attr(attr); + struct i2c_client *client = to_i2c_client(dev); + // struct as7712_32x_fan_data *data = as7712_32x_fan_update_device(dev); + ssize_t ret = 0; + int val, val2; + + switch (sda->index) { + /* case FAN_DUTY_CYCLE_PERCENTAGE: */ + /* { */ + /* u32 duty_cycle = reg_val_to_duty_cycle(data->reg_val[FAN_DUTY_CYCLE_PERCENTAGE]); */ + /* ret = sprintf(buf, "%u\n", duty_cycle); */ + /* break; */ + /* } */ + case FAN1_FRONT_SPEED_RPM: + case FAN2_FRONT_SPEED_RPM: + case FAN3_FRONT_SPEED_RPM: + case FAN4_FRONT_SPEED_RPM: + case FAN5_FRONT_SPEED_RPM: + case FAN6_FRONT_SPEED_RPM: + case FAN1_REAR_SPEED_RPM: + case FAN2_REAR_SPEED_RPM: + case FAN3_REAR_SPEED_RPM: + case FAN4_REAR_SPEED_RPM: + case FAN5_REAR_SPEED_RPM: + case FAN6_REAR_SPEED_RPM: + val = i2c_smbus_read_byte_data(client, sda->index); + ret = sprintf(buf, "%d\n", val * 150); + break; + case FAN1_FAULT: + case FAN2_FAULT: + case FAN3_FAULT: + case FAN4_FAULT: + case FAN5_FAULT: + case FAN6_FAULT: + val = i2c_smbus_read_byte_data(client, (sda->index - FAN1_FAULT)*2 + FAN1_FRONT_SPEED_RPM); + val2 = i2c_smbus_read_byte_data(client, (sda->index - FAN1_FAULT)*2 + FAN1_REAR_SPEED_RPM); + ret = sprintf(buf, "%d\n", (val|val2) ? 0 : 1); + break; + default: + break; + } + + return ret; +} + +static ssize_t fan_show_status_reg(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct sensor_device_attribute *sda = to_sensor_dev_attr(attr); + struct i2c_client *client = to_i2c_client(dev); + ssize_t ret = 0; + int val; + u8 fan_status_offset = 0; + + switch (sda->index) { + + case FAN1_PRESENT: + case FAN1_DIRECTION: + fan_status_offset = FAN1_STATUS_REG; + break; + case FAN2_PRESENT: + case FAN2_DIRECTION: + fan_status_offset = FAN2_STATUS_REG; + break; + case FAN3_PRESENT: + case FAN3_DIRECTION: + fan_status_offset = FAN3_STATUS_REG; + break; + case FAN4_PRESENT: + case FAN4_DIRECTION: + fan_status_offset = FAN4_STATUS_REG; + break; + case FAN5_PRESENT: + case FAN5_DIRECTION: + fan_status_offset = FAN5_STATUS_REG; + break; + case FAN6_PRESENT: + case FAN6_DIRECTION: + fan_status_offset = FAN6_STATUS_REG; + break; + default: + break; + } + + switch (sda->index) { + + case FAN1_PRESENT: + case FAN2_PRESENT: + case FAN3_PRESENT: + case FAN4_PRESENT: + case FAN5_PRESENT: + case FAN6_PRESENT: + val = i2c_smbus_read_byte_data(client, fan_status_offset); + /* Debug Msg + printk(KERN_ERR "%s: Present: fan_status_offset: %d, Value: %d \n", __FUNCTION__, fan_status_offset, val); + */ + ret = sprintf(buf, "%d\n", (val & FAN_PRESENT_BIT) ? 1 : 0); + break; + case FAN1_DIRECTION: + case FAN2_DIRECTION: + case FAN3_DIRECTION: + case FAN4_DIRECTION: + case FAN5_DIRECTION: + case FAN6_DIRECTION: + val = i2c_smbus_read_byte_data(client, fan_status_offset); + /* Debug Msg + printk(KERN_ERR "%s: Direction: fan_status_offset: %d, Value: %d \n", __FUNCTION__, fan_status_offset, val); + */ + ret = sprintf(buf, "%d\n", (val & FAN_DIRECTION_BIT) ? 1 : 0); + break; + default: + break; + } + + return ret; +} + +static ssize_t sys_led_read(struct device *dev, struct device_attribute *attr, char *buf) +{ + int val = 0, res = 0; + u8 command; + struct i2c_client *client = to_i2c_client(dev); + struct sensor_device_attribute *sda = to_sensor_dev_attr(attr); + + switch(sda->index) { + case SYS_LOCATOR: + case SYS_PWR: + case PORT_LED_DISABLE: + command = SYS_LED_REG; + break; + case SYS_STATUS: + case FAN1_LED: + case FAN2_LED: + case FAN3_LED: + case FAN4_LED: + case FAN5_LED: + case FAN6_LED: + command = SYS2_LED_REG; + break; + case SYS_RESET1: + command = SYS_RESET1_REG; + break; + case SYS_RESET2: + command = SYS_RESET2_REG; + break; + case SYS_RESET3: + command = SYS_RESET3_REG; + break; + } + + val = i2c_smbus_read_byte_data(client, command); + if (val < 0) { + dev_dbg(&client->dev, "fpga(0x%x) reg(0x1) err %d\n", client->addr, val); + } + + switch(sda->index) { + case SYS_LOCATOR: + res = (val & SYS_LOCATOR_LED_BITS) >> 0; + break; + case SYS_PWR: + res = (val & SYS_PWR_LED_BITS) >> 3; + break; + case PORT_LED_DISABLE: + res = (val & PORT_LED_DISABLE_BITS) >> 6; + break; + case SYS_STATUS: + res = (val & SYS_STATUS_LED_BITS) >> 0; + break; + case FAN1_LED: + case FAN3_LED: + case FAN5_LED: + case FAN2_LED: + case FAN4_LED: + case FAN6_LED: + res = (val & SYS_FAN_LED_BITS) >> 3; + break; + case SYS_RESET1: + res = val; + break; + case SYS_RESET2: + res = val; + break; + case SYS_RESET3: + res = val; + break; + } + + return sprintf(buf, "%d\n", res); +} + +static ssize_t sys_led_write(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sensor_device_attribute *sda = to_sensor_dev_attr(attr); + int error, write, command, read; + + error = kstrtoint(buf, 10, &write); + if (error) + return error; + + + switch(sda->index) { + case SYS_LOCATOR: + case SYS_PWR: + case PORT_LED_DISABLE: + if(write < 0 || write > 7) + return -EINVAL; + command = SYS_LED_REG; + break; + case SYS_STATUS: + if (write < 0 || write > 7) + return -EINVAL; + command = SYS2_LED_REG; + break; + case FAN1_LED: + case FAN2_LED: + case FAN3_LED: + case FAN4_LED: + case FAN5_LED: + case FAN6_LED: + if (write < 0 || write > 7) + return -EINVAL; + command = SYS2_LED_REG; + break; + case SYS_RESET1: + if (write < 0 || write > 255) + return -EINVAL; + command = SYS_RESET1_REG; + break; + case SYS_RESET2: + if (write < 0 || write > 255) + return -EINVAL; + command = SYS_RESET2_REG; + break; + case SYS_RESET3: + if (write < 0 || write > 255) + return -EINVAL; + command = SYS_RESET3_REG; + break; + } + + read = i2c_smbus_read_byte_data(client, command); + if (read < 0) { + dev_dbg(&client->dev, "fpga(0x%x) reg(0x1) err %d\n", client->addr, read); + } + + switch(sda->index) { + case SYS_LOCATOR: + read &= ~SYS_LOCATOR_LED_BITS; + read |= write << 0; + break; + case SYS_PWR: + read &= ~SYS_PWR_LED_BITS; + read |= write << 3; + break; + case PORT_LED_DISABLE: + read &= ~PORT_LED_DISABLE_BITS; + read |= write << 6; + break; + case SYS_STATUS: + read &= ~SYS_STATUS_LED_BITS; + read |= write << 0; + break; + case FAN1_LED: + case FAN3_LED: + case FAN5_LED: + case FAN2_LED: + case FAN4_LED: + case FAN6_LED: + read &= ~SYS_FAN_LED_BITS; + read |= write << 3; + break; + case SYS_RESET1: + read = write; + break; + case SYS_RESET2: + read = write; + break; + case SYS_RESET3: + read = write; + break; + } + + i2c_smbus_write_byte_data(client, command, read); + + return count; +} + +static ssize_t sys_sfp_write(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sensor_device_attribute *sda = to_sensor_dev_attr(attr); + int error, write, command; + + error = kstrtoint(buf, 10, &write); + if (error) + return error; + + switch(sda->index) { + case SFP_TX_FAULT: + command = SFP_TX_FAULT_MASK_REG; + break; + case SFP_PRESENT: + command = SFP_PRESENT_MASK_REG; + case SFP_RX_LOSS: + command = SFP_RX_LOSS_MASK_REG; + break; + default: + return 0; + } + + i2c_smbus_write_byte_data(client, command, write); + + return count; + +} + +static ssize_t sys_sfp_read(struct device *dev, struct device_attribute *attr, char *buf) +{ + int val = 0, res = 0; + u8 command; + struct i2c_client *client = to_i2c_client(dev); + struct sensor_device_attribute *sda = to_sensor_dev_attr(attr); + + switch(sda->index) { + case SFP_TX_FAULT: + command = SFP_TX_FAULT_REG; + break; + case SFP_TX_DISABLE: + command = SFP_TX_DISABLE_REG; + break; + case SFP_PRESENT: + command = SFP_PRESENT_REG; + break; + case SFP_RX_LOSS: + command = SFP_RX_LOSS_REG; + break; + } + + val = i2c_smbus_read_byte_data(client, command); + if (val < 0) { + dev_dbg(&client->dev, "fpga(0x%x) reg(0x1) err %d\n", client->addr, val); + } + + res = val; + + return sprintf(buf, "%d\n", res); + +} + + +static void alpha_i2c_fpga_add_client(struct i2c_client *client) +{ + struct fpga_client_node *node = kzalloc(sizeof(struct fpga_client_node), GFP_KERNEL); + + if (!node) { + dev_dbg(&client->dev, "Can't allocate fpga_client_node (0x%x)\n", client->addr); + return; + } + + node->client = client; + + mutex_lock(&list_lock); + list_add(&node->list, &fpga_client_list); + mutex_unlock(&list_lock); +} + +static void alpha_i2c_fpga_remove_client(struct i2c_client *client) +{ + struct list_head *list_node = NULL; + struct fpga_client_node *fpga_node = NULL; + int found = 0; + + mutex_lock(&list_lock); + + list_for_each(list_node, &fpga_client_list) + { + fpga_node = list_entry(list_node, struct fpga_client_node, list); + + if (fpga_node->client == client) { + found = 1; + break; + } + } + + if (found) { + list_del(list_node); + kfree(fpga_node); + } + + mutex_unlock(&list_lock); +} + +static int alpha_i2c_fpga_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + int status; + struct alphanetworks_snj60b0_320f_pwr_fpga_data* data; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { + dev_dbg(&client->dev, "i2c_check_functionality failed (0x%x)\n", client->addr); + status = -EIO; + goto exit; + } + + data = kzalloc(sizeof(struct alphanetworks_snj60b0_320f_pwr_fpga_data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + + status = sysfs_create_group(&client->dev.kobj, &alphanetworks_snj60b0_320f_fpga_group); + if (status) { + goto exit; + } + + dev_info(&client->dev, "chip found\n"); + alpha_i2c_fpga_add_client(client); + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + status = PTR_ERR(data->hwmon_dev); + goto exit; + } + + dev_info(&client->dev, "%s: pwr_fpga '%s'\n", + dev_name(data->hwmon_dev), client->name); + + return 0; + +exit: + return status; +} + +static int alpha_i2c_fpga_remove(struct i2c_client *client) +{ + struct alphanetworks_snj60b0_320f_pwr_fpga_data *data = i2c_get_clientdata(client); + sysfs_remove_group(&client->dev.kobj, &alphanetworks_snj60b0_320f_fpga_group); + alpha_i2c_fpga_remove_client(client); + kfree(data); + + return 0; +} + +static const struct i2c_device_id alpha_i2c_fpga_id[] = { + { DRIVER_NAME, 0 }, + {} +}; +MODULE_DEVICE_TABLE(i2c, alpha_i2c_fpga_id); + +static struct i2c_driver alpha_i2c_fpga_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = DRIVER_NAME, + }, + .probe = alpha_i2c_fpga_probe, + .remove = alpha_i2c_fpga_remove, + .id_table = alpha_i2c_fpga_id, + .address_list = normal_i2c, +}; + +int alpha_i2c_fpga_read(unsigned short fpga_addr, u8 reg) +{ + struct list_head *list_node = NULL; + struct fpga_client_node *fpga_node = NULL; + int ret = -EPERM; + + mutex_lock(&list_lock); + + list_for_each(list_node, &fpga_client_list) + { + fpga_node = list_entry(list_node, struct fpga_client_node, list); + + if (fpga_node->client->addr == fpga_addr) { + ret = i2c_smbus_read_byte_data(fpga_node->client, reg); + break; + } + } + + mutex_unlock(&list_lock); + + return ret; +} +EXPORT_SYMBOL(alpha_i2c_fpga_read); + +int alpha_i2c_fpga_write(unsigned short fpga_addr, u8 reg, u8 value) +{ + struct list_head *list_node = NULL; + struct fpga_client_node *fpga_node = NULL; + int ret = -EIO; + + mutex_lock(&list_lock); + + list_for_each(list_node, &fpga_client_list) + { + fpga_node = list_entry(list_node, struct fpga_client_node, list); + + if (fpga_node->client->addr == fpga_addr) { + ret = i2c_smbus_write_byte_data(fpga_node->client, reg, value); + break; + } + } + + mutex_unlock(&list_lock); + + return ret; +} +EXPORT_SYMBOL(alpha_i2c_fpga_write); + +static int __init alpha_i2c_fpga_init(void) +{ + mutex_init(&list_lock); + return i2c_add_driver(&alpha_i2c_fpga_driver); +} + +static void __exit alpha_i2c_fpga_exit(void) +{ + i2c_del_driver(&alpha_i2c_fpga_driver); +} + +static struct dmi_system_id alphanetworks_snj60b0_320f_dmi_table[] = { + { + .ident = "Alpha snj60b0-320f", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Alpha"), + DMI_MATCH(DMI_PRODUCT_NAME, "snj60b0-320f"), + }, + } +}; + +int platform_alphanetworks_snj60b0_320f(void) +{ + return dmi_check_system(alphanetworks_snj60b0_320f_dmi_table); +} +EXPORT_SYMBOL(platform_alphanetworks_snj60b0_320f); + +MODULE_AUTHOR("Alpha-SID6"); +MODULE_DESCRIPTION("alpha_power_fpga driver"); +MODULE_LICENSE("GPL"); + +module_init(alpha_i2c_fpga_init); +module_exit(alpha_i2c_fpga_exit); diff --git a/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/modules/snj60b0-320f_onie_eeprom.c b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/modules/snj60b0-320f_onie_eeprom.c new file mode 100755 index 0000000000..0462a009cc --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/modules/snj60b0-320f_onie_eeprom.c @@ -0,0 +1,267 @@ +/* + * A driver for snj60b0-320f onie eeprom + * + * Copyright (C) 2018 Alphanetworks Technology Corporation. + * Robin Chen + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * see + * + * Copyright 2006 Stefan Roese , DENX Software Engineering + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define EEPROM_SIZE 256 + +#define SYS_LED_REG 0x8 +#define FAN12_LED_REG 0x9 +#define FAN34_LED_REG 0xA +#define FAN56_LED_REG 0xB +#define SYS_RESET1_REG 0x2 + +#define SYS_LOCATOR_LED_BITS 0x01 +#define SYS_PWR_LED_BITS 0x0E +#define SYS_STATUS_LED_BITS 0x70 +#define FAN135_LED_BITS 0x07 +#define FAN246_LED_BITS 0x38 + + +extern int alpha_i2c_cpld_read(unsigned short cpld_addr, u8 reg); +extern int alpha_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value); + +static ssize_t onie_read(struct device *dev, struct device_attribute *attr, char *buf); +static ssize_t onie_write(struct device *dev, struct device_attribute *attr, const char *buf, size_t count); + +static LIST_HEAD(cpld_client_list); +static struct mutex list_lock; + +struct cpld_client_node { + struct i2c_client *client; + struct list_head list; +}; + +/* Addresses scanned for snj60b0-320f_onie_eeprom */ +static const unsigned short normal_i2c[] = { 0x56, I2C_CLIENT_END }; + + +enum sysfs_onie_attributes { + ONIE_RW, +}; + +static SENSOR_DEVICE_ATTR(eeprom, (0660), onie_read, onie_write, ONIE_RW); + +static struct attribute *snj60b0_onie_attributes[] = { + &sensor_dev_attr_eeprom.dev_attr.attr, + NULL +}; + +static const struct attribute_group snj60b0_onie_group = { + .attrs = snj60b0_onie_attributes, +}; + + +static ssize_t onie_read(struct device *dev, struct device_attribute *attr, char *buf) +{ + int val = 0, res = 0; + u8 command; + struct i2c_client *client = to_i2c_client(dev); + __u8 read_write; + unsigned short offset = 0; + union i2c_smbus_data temp; + char rbuf[EEPROM_SIZE]; + + for( offset=0 ; offset < EEPROM_SIZE ; ++offset ) + { + read_write = I2C_SMBUS_WRITE; + offset = offset & 0x3fff; + temp.byte = (u8)offset; + res = i2c_smbus_xfer(client->adapter, client->addr, client->flags=0, + read_write, 0, 2, &temp); + res = i2c_smbus_xfer(client->adapter, client->addr, client->flags=0, + read_write, 0, 2, &temp); + + read_write = I2C_SMBUS_READ; + temp.byte = 0xaa; + res = i2c_smbus_xfer(client->adapter, client->addr, client->flags=0, + read_write, 0, 1, &temp); + if (!res) + { + res = temp.byte; + rbuf[offset] = (char)temp.byte; + } + + read_write = I2C_SMBUS_READ; + temp.byte = 0xbb; + res = i2c_smbus_xfer(client->adapter, client->addr, client->flags=0, + read_write, 0, 1, &temp); + if (!res) + { + res = temp.byte; + } + } + + memcpy(buf, rbuf, EEPROM_SIZE); + return EEPROM_SIZE; +} + +static ssize_t onie_write(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + int error, write, command, read; + + error = kstrtoint(buf, 10, &write); + if (error) + return error; + + if (write < 0 || write > 255) + return -EINVAL; + + /* Not support yet */ + + return count; +} + + + +static void alpha_i2c_cpld_add_client(struct i2c_client *client) +{ + struct cpld_client_node *node = kzalloc(sizeof(struct cpld_client_node), GFP_KERNEL); + + if (!node) { + dev_dbg(&client->dev, "Can't allocate cpld_client_node (0x%x)\n", client->addr); + return; + } + + node->client = client; + + mutex_lock(&list_lock); + list_add(&node->list, &cpld_client_list); + mutex_unlock(&list_lock); +} + +static void alpha_i2c_cpld_remove_client(struct i2c_client *client) +{ + struct list_head *list_node = NULL; + struct cpld_client_node *cpld_node = NULL; + int found = 0; + + mutex_lock(&list_lock); + + list_for_each(list_node, &cpld_client_list) + { + cpld_node = list_entry(list_node, struct cpld_client_node, list); + + if (cpld_node->client == client) { + found = 1; + break; + } + } + + if (found) { + list_del(list_node); + kfree(cpld_node); + } + + mutex_unlock(&list_lock); +} + +static int onie_eeprom_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + int status; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { + dev_dbg(&client->dev, "i2c_check_functionality failed (0x%x)\n", client->addr); + status = -EIO; + goto exit; + } + + status = sysfs_create_group(&client->dev.kobj, &snj60b0_onie_group); + if (status) { + goto exit; + } + + dev_info(&client->dev, "chip found\n"); + alpha_i2c_cpld_add_client(client); + + return 0; + +exit: + return status; +} + +static int onie_eeprom_remove(struct i2c_client *client) +{ + sysfs_remove_group(&client->dev.kobj, &snj60b0_onie_group); + alpha_i2c_cpld_remove_client(client); + + return 0; +} + +static const struct i2c_device_id onie_eeprom_id[] = { + { "snj60b0_onie_eeprom", 0 }, + {} +}; +MODULE_DEVICE_TABLE(i2c, onie_eeprom_id); + +static struct i2c_driver onie_eeprom_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "snj60b0_onie_eeprom", + }, + .probe = onie_eeprom_probe, + .remove = onie_eeprom_remove, + .id_table = onie_eeprom_id, + .address_list = normal_i2c, +}; + + +static int __init onie_eeprom_init(void) +{ + mutex_init(&list_lock); + return i2c_add_driver(&onie_eeprom_driver); +} + +static void __exit onie_eeprom_exit(void) + +{ + i2c_del_driver(&onie_eeprom_driver); +} + + +MODULE_AUTHOR("Alpha-SID6"); +MODULE_DESCRIPTION("onie eeprom driver"); +MODULE_LICENSE("GPL"); + +module_init(onie_eeprom_init); +module_exit(onie_eeprom_exit); diff --git a/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/modules/snj60b0-320f_sfp.c b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/modules/snj60b0-320f_sfp.c new file mode 100755 index 0000000000..0192537696 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/modules/snj60b0-320f_sfp.c @@ -0,0 +1,2068 @@ +/* + * SFP driver for alphanetworks snj60b0-320f sfp + * + * Copyright (C) 2019 Alphanetworks Technology Corporation. + * Philip Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * see + * + * Copyright (C) Brandon Chuang + * + * Copyright 2006 Stefan Roese , DENX Software Engineering + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRIVER_NAME "snj60b0-320f_sfp" + +#define DEBUG_MODE 0 + +#if (DEBUG_MODE == 1) + #define DEBUG_PRINT(fmt, args...) \ + printk (KERN_INFO "[%s,%d]: " fmt "\r\n", __FUNCTION__, __LINE__, ##args) +#else + #define DEBUG_PRINT(fmt, args...) +#endif + +#define NUM_OF_SFP_PORT 32 +#define EEPROM_NAME "sfp_eeprom" +#define EEPROM_SIZE 256 /* 256 byte eeprom */ +#define BIT_INDEX(i) (1ULL << (i)) +#define USE_I2C_BLOCK_READ 1 +#define I2C_RW_RETRY_COUNT 3 +#define I2C_RW_RETRY_INTERVAL 100 /* ms */ + +#define SFP_CPLD_I2C_ADDR 0x5F +//#define SFP_FPGA_I2C_ADDR 0x5E +#define SFP_EEPROM_A0_I2C_ADDR 0x50 +#define SFP_EEPROM_A2_I2C_ADDR 0x68 + +#define SFPPLUS_1_PORT_NUMBER 32 +#define SFPPLUS_2_PORT_NUMBER 33 + +#define SFPPLUS_PRESENT_ADDRESS 0x28 + +#define SFP_CPLD_REG_ADDR_REVISION 0x00 +#define SFP_CPLD_REG_ADDR_PRESENT 0x03 +#define SFP_CPLD_REG_ADDR_RESET 0x04 +#define SFP_CPLD_REG_ADDR_LOWPOWERMODE 0x05 +#define SFP_CPLD_REG_ADDR_MODSELECT 0x06 +#define SFP_CPLD_REG_ADDR_LED 0x07 + +#define SFP_CPLD_REVISION_BIT 0xF + +u8 portCPLDID_0[]={13,14,15,16}; +u8 sfpPlusID_0[]={12,11}; +u8 portCPLDID_1[]={14,15,16,17}; +u8 sfpPlusID_1[]={13,12}; +u8 *portCPLDID; +u8 *sfpPlusID; + + +#define SFF8024_PHYSICAL_DEVICE_ID_ADDR 0x0 +#define SFF8024_DEVICE_ID_SFP 0x3 +#define SFF8024_DEVICE_ID_QSFP 0xC +#define SFF8024_DEVICE_ID_QSFP_PLUS 0xD +#define SFF8024_DEVICE_ID_QSFP28 0x11 +#define SFF8024_DEVICE_ID_QSFPDD 0x18 + +#define SFF8472_DIAG_MON_TYPE_ADDR 92 +#define SFF8472_DIAG_MON_TYPE_DDM_MASK 0x40 +#define SFF8472_10G_ETH_COMPLIANCE_ADDR 0x3 +#define SFF8472_10G_BASE_MASK 0xF0 + +#define SFF8436_RX_LOS_ADDR 3 +#define SFF8436_TX_FAULT_ADDR 4 +#define SFF8436_TX_DISABLE_ADDR 86 + +static ssize_t sfp_eeprom_read(struct i2c_client *, u8, u8 *,int); +static ssize_t sfp_eeprom_write(struct i2c_client *, u8 , const char *,int); +/* extern int alpha_i2c_cpld_read(unsigned short cpld_addr, u8 reg); */ +extern int alpha_i2c_fpga_write(unsigned short cpld_addr, u8 reg, u8 value); + +/* Addresses scanned + */ +static const unsigned short normal_i2c[] = { SFP_EEPROM_A0_I2C_ADDR, SFP_EEPROM_A2_I2C_ADDR, SFP_CPLD_I2C_ADDR, I2C_CLIENT_END }; + +#define CPLD_PORT_TO_FRONT_PORT(port) (port+1) + +enum port_numbers { +sfp1, sfp2, sfp3, sfp4, sfp5, sfp6, sfp7, sfp8, +sfp9, sfp10, sfp11, sfp12, sfp13, sfp14, sfp15, sfp16, +sfp17, sfp18, sfp19, sfp20, sfp21, sfp22, sfp23, sfp24, +sfp25, sfp26, sfp27, sfp28, sfp29, sfp30, sfp31, sfp32, +sfp33, sfp34 +}; + +static const struct i2c_device_id sfp_device_id[] = { +{ "sfpcpld1", sfp1 }, { "sfpcpld2", sfp2 }, { "sfpcpld3", sfp3 }, { "sfpcpld4", sfp4 }, +{ "sfpcpld5", sfp5 }, { "sfpcpld6", sfp6 }, { "sfpcpld7", sfp7 }, { "sfpcpld8", sfp8 }, +{ "sfpcpld9", sfp9 }, { "sfpcpld10", sfp10 }, { "sfpcpld11", sfp11 }, { "sfpcpld12", sfp12 }, +{ "sfpcpld13", sfp13 }, { "sfpcpld14", sfp14 }, { "sfpcpld15", sfp15 }, { "sfpcpld16", sfp16 }, +{ "sfpcpld17", sfp17 }, { "sfpcpld18", sfp18 }, { "sfpcpld19", sfp19 }, { "sfpcpld20", sfp20 }, +{ "sfpcpld21", sfp21 }, { "sfpcpld22", sfp22 }, { "sfpcpld23", sfp23 }, { "sfpcpld24", sfp24 }, +{ "sfpcpld25", sfp25 }, { "sfpcpld26", sfp26 }, { "sfpcpld27", sfp27 }, { "sfpcpld28", sfp28 }, +{ "sfpcpld29", sfp29 }, { "sfpcpld30", sfp30 }, { "sfpcpld31", sfp31 }, { "sfpcpld32", sfp32 }, +{ "sfpcpld33", sfp33 }, { "sfpcpld34", sfp34 }, +{} +}; +MODULE_DEVICE_TABLE(i2c, sfp_device_id); + +/* + * list of valid port types + * note OOM_PORT_TYPE_NOT_PRESENT to indicate no + * module is present in this port + */ +typedef enum oom_driver_port_type_e { + OOM_DRIVER_PORT_TYPE_INVALID, + OOM_DRIVER_PORT_TYPE_NOT_PRESENT, + OOM_DRIVER_PORT_TYPE_SFP, + OOM_DRIVER_PORT_TYPE_SFP_PLUS, + OOM_DRIVER_PORT_TYPE_QSFP, + OOM_DRIVER_PORT_TYPE_QSFP_PLUS, + OOM_DRIVER_PORT_TYPE_QSFP28, + OOM_DRIVER_PORT_TYPE_QSFPDD +} oom_driver_port_type_t; + +enum driver_type_e { + DRIVER_TYPE_SFP_MSA, + DRIVER_TYPE_SFP_DDM, + DRIVER_TYPE_QSFP +}; + +/* Each client has this additional data + */ +struct eeprom_data { + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + struct bin_attribute bin; /* eeprom data */ +}; + +struct sfp_msa_data { + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u64 status[2]; /* index 0 => device id + 1 => 10G Ethernet Compliance Codes + to distinguish SFP or SFP+ + 2 => DIAGNOSTIC MONITORING TYPE */ + struct eeprom_data eeprom; +}; + +struct sfp_ddm_data { + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u64 status[3]; /* bit0:port0, bit1:port1 and so on */ + /* index 0 => tx_fail + 1 => tx_disable + 2 => rx_loss */ + struct eeprom_data eeprom; +}; + +struct qsfp_data { + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 status[3]; /* bit0:port0, bit1:port1 and so on */ + /* index 0 => tx_fail + 1 => tx_disable + 2 => rx_loss */ + + u8 device_id; + struct eeprom_data eeprom; +}; + +struct sfp_port_data { + struct mutex update_lock; + enum driver_type_e driver_type; + int port; /* CPLD port index */ + oom_driver_port_type_t port_type; + u64 present; /* present status, bit0:port0, bit1:port1 and so on */ + u64 port_reset; /* reset status, bit0:port0, bit1:port1 and so on */ + u64 port_lpmode; /* lpmode status, bit0:port0, bit1:port1 and so on */ + u64 port_led; /* port led status, bit0:port0, bit1:port1 and so on */ + + struct sfp_msa_data *msa; + struct sfp_ddm_data *ddm; + struct qsfp_data *qsfp; + + struct i2c_client *client; +}; + +enum sfp_sysfs_port_num_attributes { + PORT1_NUMBER, + PORT2_NUMBER, + PORT3_NUMBER, + PORT4_NUMBER, + PORT5_NUMBER, + PORT6_NUMBER, + PORT7_NUMBER, + PORT8_NUMBER, + PORT_NUMBER_MAX +}; + +enum sfp_sysfs_present_attributes { + PORT1_PRESENT, + PORT2_PRESENT, + PORT3_PRESENT, + PORT4_PRESENT, + PORT5_PRESENT, + PORT6_PRESENT, + PORT7_PRESENT, + PORT8_PRESENT, + PORT1_PRESENT_ALL, + PORT2_PRESENT_ALL, + PORT3_PRESENT_ALL, + PORT4_PRESENT_ALL, + PORT5_PRESENT_ALL, + PORT6_PRESENT_ALL, + PORT7_PRESENT_ALL, + PORT8_PRESENT_ALL, + PORT_PRESENT_MAX +}; + +enum sfp_sysfs_type_attributes { + PORT1_TYPE, + PORT2_TYPE, + PORT3_TYPE, + PORT4_TYPE, + PORT5_TYPE, + PORT6_TYPE, + PORT7_TYPE, + PORT8_TYPE, + PORT_TYPE_MAX +}; + +enum sfp_sysfs_reset_attributes { + PORT1_RESET, + PORT2_RESET, + PORT3_RESET, + PORT4_RESET, + PORT5_RESET, + PORT6_RESET, + PORT7_RESET, + PORT8_RESET, + PORT_RESET_MAX +}; + +enum sfp_sysfs_rx_los_attributes { + PORT1_RX_LOS, + PORT2_RX_LOS, + PORT3_RX_LOS, + PORT4_RX_LOS, + PORT5_RX_LOS, + PORT6_RX_LOS, + PORT7_RX_LOS, + PORT8_RX_LOS, + PORT_RX_LOS_MAX +}; + +enum sfp_sysfs_rx_los1_attributes { + PORT1_RX_LOS1 = PORT_RX_LOS_MAX, + PORT2_RX_LOS1, + PORT3_RX_LOS1, + PORT4_RX_LOS1, + PORT5_RX_LOS1, + PORT6_RX_LOS1, + PORT7_RX_LOS1, + PORT8_RX_LOS1, + PORT_RX_LOS1_MAX +}; + +enum sfp_sysfs_rx_los2_attributes { + PORT1_RX_LOS2 = PORT_RX_LOS1_MAX, + PORT2_RX_LOS2, + PORT3_RX_LOS2, + PORT4_RX_LOS2, + PORT5_RX_LOS2, + PORT6_RX_LOS2, + PORT7_RX_LOS2, + PORT8_RX_LOS2, + PORT_RX_LOS2_MAX +}; + +enum sfp_sysfs_rx_los3_attributes { + PORT1_RX_LOS3 = PORT_RX_LOS2_MAX, + PORT2_RX_LOS3, + PORT3_RX_LOS3, + PORT4_RX_LOS3, + PORT5_RX_LOS3, + PORT6_RX_LOS3, + PORT7_RX_LOS3, + PORT8_RX_LOS3, + PORT_RX_LOS3_MAX +}; + +enum sfp_sysfs_rx_los4_attributes { + PORT1_RX_LOS4 = PORT_RX_LOS3_MAX, + PORT2_RX_LOS4, + PORT3_RX_LOS4, + PORT4_RX_LOS4, + PORT5_RX_LOS4, + PORT6_RX_LOS4, + PORT7_RX_LOS4, + PORT8_RX_LOS4, + PORT_RX_LOS4_MAX +}; + +enum sfp_sysfs_rx_los_all_attributes { + PORT1_RX_LOS_ALL = PORT_RX_LOS4_MAX, + PORT2_RX_LOS_ALL, + PORT3_RX_LOS_ALL, + PORT4_RX_LOS_ALL, + PORT5_RX_LOS_ALL, + PORT6_RX_LOS_ALL, + PORT7_RX_LOS_ALL, + PORT8_RX_LOS_ALL, + PORT_RX_LOS_ALL_MAX +}; + +enum sfp_sysfs_tx_disable_attributes { + PORT1_TX_DISABLE = PORT_RX_LOS_ALL_MAX, + PORT2_TX_DISABLE, + PORT3_TX_DISABLE, + PORT4_TX_DISABLE, + PORT5_TX_DISABLE, + PORT6_TX_DISABLE, + PORT7_TX_DISABLE, + PORT8_TX_DISABLE, + PORT_TX_DISABLE_MAX +}; + +enum sfp_sysfs_tx_disable1_attributes { + PORT1_TX_DISABLE1 = PORT_TX_DISABLE_MAX, + PORT2_TX_DISABLE1, + PORT3_TX_DISABLE1, + PORT4_TX_DISABLE1, + PORT5_TX_DISABLE1, + PORT6_TX_DISABLE1, + PORT7_TX_DISABLE1, + PORT8_TX_DISABLE1, + PORT_TX_DISABLE1_MAX +}; + +enum sfp_sysfs_tx_disable2_attributes { + PORT1_TX_DISABLE2 = PORT_TX_DISABLE1_MAX, + PORT2_TX_DISABLE2, + PORT3_TX_DISABLE2, + PORT4_TX_DISABLE2, + PORT5_TX_DISABLE2, + PORT6_TX_DISABLE2, + PORT7_TX_DISABLE2, + PORT8_TX_DISABLE2, + PORT_TX_DISABLE2_MAX +}; + +enum sfp_sysfs_tx_disable3_attributes { + PORT1_TX_DISABLE3 = PORT_TX_DISABLE2_MAX, + PORT2_TX_DISABLE3, + PORT3_TX_DISABLE3, + PORT4_TX_DISABLE3, + PORT5_TX_DISABLE3, + PORT6_TX_DISABLE3, + PORT7_TX_DISABLE3, + PORT8_TX_DISABLE3, + PORT_TX_DISABLE3_MAX +}; + +enum sfp_sysfs_tx_disable4_attributes { + PORT1_TX_DISABLE4 = PORT_TX_DISABLE3_MAX, + PORT2_TX_DISABLE4, + PORT3_TX_DISABLE4, + PORT4_TX_DISABLE4, + PORT5_TX_DISABLE4, + PORT6_TX_DISABLE4, + PORT7_TX_DISABLE4, + PORT8_TX_DISABLE4, + PORT_TX_DISABLE4_MAX +}; + +enum sfp_sysfs_tx_fault_attributes { + PORT1_TX_FAULT = PORT_TX_DISABLE4_MAX, + PORT2_TX_FAULT, + PORT3_TX_FAULT, + PORT4_TX_FAULT, + PORT5_TX_FAULT, + PORT6_TX_FAULT, + PORT7_TX_FAULT, + PORT8_TX_FAULT, + PORT_TX_FAULT_MAX +}; + +enum sfp_sysfs_tx_fault1_attributes { + PORT1_TX_FAULT1 = PORT_TX_FAULT_MAX, + PORT2_TX_FAULT1, + PORT3_TX_FAULT1, + PORT4_TX_FAULT1, + PORT5_TX_FAULT1, + PORT6_TX_FAULT1, + PORT7_TX_FAULT1, + PORT8_TX_FAULT1, + PORT_TX_FAULT1_MAX +}; + +enum sfp_sysfs_tx_fault2_attributes { + PORT1_TX_FAULT2 = PORT_TX_FAULT1_MAX, + PORT2_TX_FAULT2, + PORT3_TX_FAULT2, + PORT4_TX_FAULT2, + PORT5_TX_FAULT2, + PORT6_TX_FAULT2, + PORT7_TX_FAULT2, + PORT8_TX_FAULT2, + PORT_TX_FAULT2_MAX +}; + +enum sfp_sysfs_tx_fault3_attributes { + PORT1_TX_FAULT3 = PORT_TX_FAULT2_MAX, + PORT2_TX_FAULT3, + PORT3_TX_FAULT3, + PORT4_TX_FAULT3, + PORT5_TX_FAULT3, + PORT6_TX_FAULT3, + PORT7_TX_FAULT3, + PORT8_TX_FAULT3, + PORT_TX_FAULT3_MAX +}; + +enum sfp_sysfs_tx_fault4_attributes { + PORT1_TX_FAULT4 = PORT_TX_FAULT3_MAX, + PORT2_TX_FAULT4, + PORT3_TX_FAULT4, + PORT4_TX_FAULT4, + PORT5_TX_FAULT4, + PORT6_TX_FAULT4, + PORT7_TX_FAULT4, + PORT8_TX_FAULT4, + PORT_TX_FAULT4_MAX +}; + +enum sfp_sysfs_lpmode_attributes { + PORT1_LPMODE, + PORT2_LPMODE, + PORT3_LPMODE, + PORT4_LPMODE, + PORT5_LPMODE, + PORT6_LPMODE, + PORT7_LPMODE, + PORT8_LPMODE, + PORT_LPMODE_MAX +}; + +enum sfp_sysfs_eeprom_attributes { + PORT1_EEPROM, + PORT2_EEPROM, + PORT3_EEPROM, + PORT4_EEPROM, + PORT5_EEPROM, + PORT6_EEPROM, + PORT7_EEPROM, + PORT8_EEPROM, + PORT_EEPROM_MAX +}; + +enum sfp_sysfs_ddm_implemented_attributes { + PORT1_DDM_IMPLEMENTED, + PORT2_DDM_IMPLEMENTED, + PORT3_DDM_IMPLEMENTED, + PORT4_DDM_IMPLEMENTED, + PORT5_DDM_IMPLEMENTED, + PORT6_DDM_IMPLEMENTED, + PORT7_DDM_IMPLEMENTED, + PORT8_DDM_IMPLEMENTED, + PORT_DDM_IMPLEMENTED_MAX +}; + +enum sfp_sysfs_port_led_attributes { + PORT_LED, + PORT_LED_MAX +}; + +enum sfp_sysfs_cpld_revision_attributes { + CPLD_REVISION, + CPLD_REVISION_MAX +}; + +static ssize_t show_cpld_version(struct device *dev, struct device_attribute *attr, char *buf) +{ + int val = 0; + struct i2c_client *client = to_i2c_client(dev); + + if (client->addr == SFP_CPLD_I2C_ADDR) + { + val = i2c_smbus_read_byte_data(client, SFP_CPLD_REG_ADDR_REVISION); + + if (val < 0) { + dev_dbg(&client->dev, "cpld(0x%x) reg(0x0) err %d\n", client->addr, val); + } + } + + return sprintf(buf, "%d\n", (val & SFP_CPLD_REVISION_BIT)); +} + +static ssize_t show_port_number(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + DEBUG_PRINT("show_port_number port number:%d", data->port + attr->index); + return sprintf(buf, "%d\n", CPLD_PORT_TO_FRONT_PORT(data->port + attr->index)); +} + +static struct sfp_port_data *sfp_plus_update_present(struct i2c_client *client) +{ + struct sfp_port_data *data = i2c_get_clientdata(client); + int i = 0; + int status = -1; + u8 regs[] = {SFPPLUS_PRESENT_ADDRESS}; + + DEBUG_PRINT("Starting sfp+ present status update"); + mutex_lock(&data->update_lock); + + /* Read present status of port */ + data->present = 0; + + for (i = 0; i < ARRAY_SIZE(regs); i++) { + /* status = alpha_i2c_cpld_read(0x5f, regs[i]); */ + status = i2c_smbus_read_byte_data(client, regs[i]); + + if (status < 0) { + DEBUG_PRINT("SFP+ reg(0x%x) err %d", regs[i], status); + goto exit; + } + + DEBUG_PRINT("Status:%d", status); + + if(data->port == SFPPLUS_1_PORT_NUMBER) + data->present = ((status & 0x2) == 0)?0x1:0; + else + data->present = ((status & 0x1) == 0)?0x2:0; + } + + DEBUG_PRINT("Present status = 0x%llx", data->present); +exit: + mutex_unlock(&data->update_lock); + return data; +} + +static struct sfp_port_data *sfp_update_present(struct i2c_client *client) +{ + struct sfp_port_data *data = i2c_get_clientdata(client); + int i = 0; + int status = -1; + u8 regs[] = {SFP_CPLD_REG_ADDR_PRESENT}; + + if(data->port >= SFPPLUS_1_PORT_NUMBER){ + if(client->addr == SFP_EEPROM_A0_I2C_ADDR) + return sfp_plus_update_present(client); + else{ + data->present = 0; + return data; + } + } + + DEBUG_PRINT("Starting sfp present status update"); + mutex_lock(&data->update_lock); + + /* Read present status of port 1~32 */ + data->present = 0; + + for (i = 0; i < ARRAY_SIZE(regs); i++) { + status = i2c_smbus_read_byte_data(client, regs[i]); + + if (status < 0) { + DEBUG_PRINT("cpld(%d) reg(0x%x) err %d", SFP_CPLD_I2C_ADDR, regs[i], status); + goto exit; + } + DEBUG_PRINT("Present status = 0x%x", status); + + data->present |= (u64)status << (i*8); + DEBUG_PRINT("Present status = 0x%llx", data->present); + } + + DEBUG_PRINT("Present status = 0x%llx", data->present); +exit: + mutex_unlock(&data->update_lock); + return data; +} + +static struct sfp_port_data *sfp_update_tx_rx_status(struct device *dev) +{ + return NULL; +} + +static ssize_t sfp_set_tx_disable(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + return 0; +} + +static int sfp_is_port_present(struct i2c_client *client, int port) +{ + struct sfp_port_data *data = sfp_update_present(client); + return (data->present & BIT_INDEX(port)) ? 1 : 0; +} + +static ssize_t show_present(struct device *dev, struct device_attribute *da, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + + if ((attr->index >= PORT1_PRESENT_ALL) && (attr->index <= PORT8_PRESENT_ALL)) { + } + + /* PRESENT */ + return sprintf(buf, "%d\n", sfp_is_port_present(client, attr->index)); +} + +static struct sfp_port_data *sfp_update_port_type(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + u8 buf = 0; + int status; + + mutex_lock(&data->update_lock); + + switch (data->driver_type) { + case DRIVER_TYPE_SFP_MSA: + { + status = sfp_eeprom_read(data->client, SFF8024_PHYSICAL_DEVICE_ID_ADDR, &buf, sizeof(buf)); + if (status < 0) { + data->port_type = OOM_DRIVER_PORT_TYPE_INVALID; + break; + } + + if (buf != SFF8024_DEVICE_ID_SFP) { + data->port_type = OOM_DRIVER_PORT_TYPE_INVALID; + break; + } + + status = sfp_eeprom_read(data->client, SFF8472_10G_ETH_COMPLIANCE_ADDR, &buf, sizeof(buf)); + if (status < 0) { + data->port_type = OOM_DRIVER_PORT_TYPE_INVALID; + break; + } + + DEBUG_PRINT("sfp port type (0x3) data = (0x%x)", buf); + data->port_type = buf & SFF8472_10G_BASE_MASK ? OOM_DRIVER_PORT_TYPE_SFP_PLUS : OOM_DRIVER_PORT_TYPE_SFP; + break; + } + case DRIVER_TYPE_QSFP: + { + status = sfp_eeprom_read(data->client, SFF8024_PHYSICAL_DEVICE_ID_ADDR, &buf, sizeof(buf)); + if (status < 0) { + data->port_type = OOM_DRIVER_PORT_TYPE_INVALID; + break; + } + + DEBUG_PRINT("qsfp port type (0x0) buf = (0x%x)", buf); + switch (buf) { + case SFF8024_DEVICE_ID_QSFP: + data->port_type = OOM_DRIVER_PORT_TYPE_QSFP; + break; + case SFF8024_DEVICE_ID_QSFP_PLUS: + data->port_type = OOM_DRIVER_PORT_TYPE_QSFP_PLUS; + break; + case SFF8024_DEVICE_ID_QSFP28: + data->port_type = OOM_DRIVER_PORT_TYPE_QSFP28; + break; + case SFF8024_DEVICE_ID_QSFPDD: + data->port_type = OOM_DRIVER_PORT_TYPE_QSFPDD; + break; + default: + data->port_type = OOM_DRIVER_PORT_TYPE_INVALID; + break; + } + + break; + } + default: + break; + } + + mutex_unlock(&data->update_lock); + return data; +} + +static ssize_t show_port_type(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + if (!sfp_is_port_present(client, attr->index)) { + return sprintf(buf, "%d\n", OOM_DRIVER_PORT_TYPE_NOT_PRESENT); + } + + sfp_update_port_type(dev); + return sprintf(buf, "%d\n", data->port_type); +} + + +static struct sfp_port_data *sfp_update_port_reset(struct i2c_client *client) +{ + struct sfp_port_data *data = i2c_get_clientdata(client); + int i = 0; + int status = -1; + u8 regs[] = {SFP_CPLD_REG_ADDR_RESET}; + + mutex_lock(&data->update_lock); + + /* Read reset status of port 1~32 */ + data->port_reset = 0; + + for (i = 0; i < ARRAY_SIZE(regs); i++) { + status = i2c_smbus_read_byte_data(client, regs[i]); + + if (status < 0) { + DEBUG_PRINT("cpld(0x%x) reg(0x%x) err %d", SFP_CPLD_REG_ADDR_RESET, regs[i], status); + goto exit; + } + + DEBUG_PRINT("reset status = 0x%x", status); + data->port_reset |= (u64)status << (i*8); + } + + DEBUG_PRINT("reset status = 0x%llx", data->port_reset); +exit: + mutex_unlock(&data->update_lock); + return data; +} + +static ssize_t show_port_reset(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + int is_reset = 0; + + if (!sfp_is_port_present(client, attr->index)) { + return sprintf(buf, "%d\n", OOM_DRIVER_PORT_TYPE_NOT_PRESENT); + } + + sfp_update_port_reset(client); + is_reset = (data->port_reset & BIT_INDEX(attr->index)); + + return sprintf(buf, "%d\n", is_reset); +} + +static ssize_t sfp_set_port_reset(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + u8 cpld_reg = 0, cpld_val = 0; /*, cpld_bit = 0; //remove unused variable */ + long is_reset; + int error; + + error = kstrtol(buf, 10, &is_reset); + if (error) { + return error; + } + + mutex_lock(&data->update_lock); + + cpld_reg = SFP_CPLD_REG_ADDR_RESET; + + cpld_val = i2c_smbus_read_byte_data(client, cpld_reg); + + DEBUG_PRINT("current cpld reg = 0x%x value = 0x%x", cpld_reg, cpld_val); + + /* Update reset status. CPLD defined 0 is reset state, 1 is normal state. + * is_reset: 0 is not reset. 1 is reset. + */ + if (is_reset == 1) { + cpld_val |= BIT_INDEX(attr->index); + } + else { + cpld_val &= ~BIT_INDEX(attr->index); + } + + i2c_smbus_write_byte_data(client, cpld_reg, cpld_val); + DEBUG_PRINT("write cpld reg = 0x%x value = 0x%x", cpld_reg, cpld_val); + + mutex_unlock(&data->update_lock); + + return count; +} + +static struct sfp_port_data *qsfp_update_tx_rx_status(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + int i, status = -1; + u8 buf = 0; + u8 reg[] = {SFF8436_TX_FAULT_ADDR, SFF8436_TX_DISABLE_ADDR, SFF8436_RX_LOS_ADDR}; + + if (time_before(jiffies, data->qsfp->last_updated + HZ + HZ / 2) && data->qsfp->valid) { + return data; + } + + dev_dbg(dev, "Starting sfp tx rx status update"); + mutex_lock(&data->update_lock); + data->qsfp->valid = 0; + memset(data->qsfp->status, 0, sizeof(data->qsfp->status)); + + /* Notify device to update tx fault/ tx disable/ rx los status */ + for (i = 0; i < ARRAY_SIZE(reg); i++) { + status = sfp_eeprom_read(data->client, reg[i], &buf, sizeof(buf)); + if (status < 0) { + goto exit; + } + } + msleep(200); + + /* Read actual tx fault/ tx disable/ rx los status */ + for (i = 0; i < ARRAY_SIZE(reg); i++) { + status = sfp_eeprom_read(data->client, reg[i], &buf, sizeof(buf)); + if (status < 0) { + goto exit; + } + + DEBUG_PRINT("qsfp reg(0x%x) status = (0x%x)", reg[i], data->qsfp->status[i]); + data->qsfp->status[i] = (buf & 0xF); + } + + data->qsfp->valid = 1; + data->qsfp->last_updated = jiffies; + mutex_unlock(&data->update_lock); + return data; + +exit: + mutex_unlock(&data->update_lock); + return NULL; +} + +static ssize_t qsfp_show_tx_rx_status(struct device *dev, struct device_attribute *da, + char *buf) +{ + u8 val = 0; + struct i2c_client *client = to_i2c_client(dev); + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct sfp_port_data *data = i2c_get_clientdata(client); + + if (!sfp_is_port_present(client, attr->index)) { + return -ENODEV; + } + + data = qsfp_update_tx_rx_status(dev); + if (!data) { + return -EIO; + } + + if ((attr->index >= PORT1_TX_FAULT) && (attr->index < PORT_TX_FAULT4_MAX)){ + if (attr->index < PORT_TX_FAULT_MAX) + val = ((data->qsfp->status[2] & 0xF) == 0xF) ? 1 : 0; + else + val = (data->qsfp->status[2] & BIT_INDEX(attr->index - PORT1_TX_FAULT1)) ? 1 : 0; + } + else if ((attr->index >= PORT1_TX_DISABLE) && (attr->index < PORT_TX_DISABLE4_MAX)){ + if (attr->index < PORT_TX_DISABLE_MAX) + val = ((data->qsfp->status[1] & 0xF) == 0xF) ? 1 : 0; + else + val = (data->qsfp->status[1] & BIT_INDEX(attr->index - PORT1_TX_DISABLE1)) ? 1 : 0; + } + if ((attr->index >= PORT1_RX_LOS) && (attr->index < PORT_RX_LOS4_MAX)){ + if (attr->index < PORT_RX_LOS_MAX) + val = ((data->qsfp->status[0] & 0xf) == 0xf) ? 1 : 0; + else + val = (data->qsfp->status[0] & BIT_INDEX(attr->index - PORT1_RX_LOS1)) ? 1 : 0; + } + + return sprintf(buf, "%d\n", val); +} + +static ssize_t qsfp_set_tx_disable(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + long disable; + int result; + struct i2c_client *client = to_i2c_client(dev); + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct sfp_port_data *data; + + result = kstrtol(buf, 10, &disable); + if (result) { + return result; + } + + data = qsfp_update_tx_rx_status(dev); + if (!data) { + return -EIO; + } + + mutex_lock(&data->update_lock); + + if((attr->index >= PORT1_TX_DISABLE) && (attr->index < PORT_TX_DISABLE_MAX)){ + DEBUG_PRINT ("disable:%ld %d==TX_DISABLE %u\r\n", disable, attr->index, data->qsfp->status[1]); + data->qsfp->status[1] = disable? 0xF:0; + } + else{ + if (disable) { + data->qsfp->status[1] |= (1 << (attr->index - PORT1_TX_DISABLE1)); + } + else { + data->qsfp->status[1] &= ~(1 << (attr->index - PORT1_TX_DISABLE1)); + } + } + + DEBUG_PRINT("index = (%d), status = (0x%x)", attr->index, data->qsfp->status[1]); + result = sfp_eeprom_write(client, SFF8436_TX_DISABLE_ADDR, &data->qsfp->status[1], sizeof(data->qsfp->status[1])); + mutex_unlock(&data->update_lock); + return count; +} + +static struct sfp_port_data *qsfp_update_port_led(struct i2c_client *client) +{ + struct sfp_port_data *data = i2c_get_clientdata(client); + int status = -1; + u8 reg = SFP_CPLD_REG_ADDR_LED; + + mutex_lock(&data->update_lock); + + /* Read led status of port 1~32 */ + data->port_led = 0; + + status = i2c_smbus_read_byte_data(client, reg); + + if (status < 0) { + DEBUG_PRINT("cpld reg(0x%x) err %d", reg, status); + goto exit; + } + + data->port_led = status; + + DEBUG_PRINT("led status = %ll", data->port_led); +exit: + mutex_unlock(&data->update_lock); + return data; +} + +static ssize_t qsfp_show_port_led(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + data = qsfp_update_port_led(client); + + return sprintf(buf, "%ll\n", data->port_led); +} + +static ssize_t qsfp_set_port_led(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + u8 cpld_reg = 0, cpld_val = 0; /*, cpld_bit = 0; //remove unused variable */ + long led_state; + int error; + int result; + + error = kstrtol(buf, 10, &led_state); + if (error) { + return error; + } + + mutex_lock(&data->update_lock); + + cpld_reg = SFP_CPLD_REG_ADDR_LED; + + cpld_val = i2c_smbus_read_byte_data(client, cpld_reg); + + DEBUG_PRINT("current cpld reg = 0x%x value = 0x%x", cpld_reg, cpld_val); + + /* Update led status. CPLD defined 0 is LED enable, 1 is LED disable. + * led_state: 0 is LED enable. 1 is LED disable. + */ + if (cpld_val != led_state){ + data->port_led = led_state; + + result = i2c_smbus_write_byte_data(client, cpld_reg, led_state); + if (result < 0) { + dev_info(&client->dev, "%s, i2c_smbus_write_byte_data fail(%d)", __FUNCTION__, result); + } + DEBUG_PRINT("write cpld reg = 0x%x value = 0x%x", cpld_reg, led_state); + } + + mutex_unlock(&data->update_lock); + + return count; +} + +static struct sfp_port_data *qsfp_update_port_lpmode(struct i2c_client *client) +{ + struct sfp_port_data *data = i2c_get_clientdata(client); + int i = 0; + int status = -1; + u8 regs[] = {SFP_CPLD_REG_ADDR_LOWPOWERMODE}; + + mutex_lock(&data->update_lock); + + /* Read lpmode status of port 1~32 */ + data->port_lpmode = 0; + + for (i = 0; i < ARRAY_SIZE(regs); i++) { + status = i2c_smbus_read_byte_data(client, regs[i]); + + if (status < 0) { + DEBUG_PRINT("cpld reg(0x%x) err %d", regs[i], status); + goto exit; + } + + DEBUG_PRINT("lpmode status = 0x%x", status); + data->port_lpmode |= (u64)status << (i*8); + } + + DEBUG_PRINT("lpmode status = 0x%llx", data->port_lpmode); +exit: + mutex_unlock(&data->update_lock); + return data; +} + +static ssize_t qsfp_show_port_lpmode(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + int is_lpmode = 0; + + qsfp_update_port_lpmode(client); + is_lpmode = (data->port_lpmode & BIT_INDEX(attr->index))?1:0; + + return sprintf(buf, "%d\n", is_lpmode); +} + +static ssize_t qsfp_set_port_lpmode(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + u8 cpld_reg = 0, cpld_val = 0; + long is_lpmode; + int error; + + error = kstrtol(buf, 10, &is_lpmode); + if (error) { + return error; + } + + mutex_lock(&data->update_lock); + + cpld_reg = SFP_CPLD_REG_ADDR_LOWPOWERMODE; + + cpld_val = i2c_smbus_read_byte_data(client, cpld_reg); + + DEBUG_PRINT("current cpld reg = 0x%x value = 0x%x", cpld_reg, cpld_val); + + /* Update lpmode status. CPLD defined 0 is normal mode, 1 is Low Power mode. + * is_lpmode: 0 is normal mode. 1 is Low Power mode. + */ + if (is_lpmode == 1) { + cpld_val |= BIT_INDEX(attr->index); + } + else { + cpld_val &= ~BIT_INDEX(attr->index); + } + + i2c_smbus_write_byte_data(client, cpld_reg, cpld_val); + DEBUG_PRINT("write cpld reg = 0x%x value = 0x%x", cpld_reg, cpld_val); + + mutex_unlock(&data->update_lock); + + return count; +} + +static ssize_t sfp_show_ddm_implemented(struct device *dev, struct device_attribute *da, + char *buf) +{ + int status; + char ddm; + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + if (!sfp_is_port_present(client, attr->index)) { + return -ENODEV; + } + + status = sfp_eeprom_read(data->client, SFF8472_DIAG_MON_TYPE_ADDR, &ddm, sizeof(ddm)); + if (status < 0) { + return -EIO; + } + + return sprintf(buf, "%d\n", (ddm & SFF8472_DIAG_MON_TYPE_DDM_MASK) ? 1 : 0); +} + +static ssize_t sfp_show_tx_rx_status(struct device *dev, struct device_attribute *da, + char *buf) +{ + u8 val = 0, index = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct sfp_port_data *data; + + data = sfp_update_tx_rx_status(dev); + if (!data) { + return -EIO; + } + if ((attr->index >= PORT1_TX_FAULT) && (attr->index < PORT_TX_FAULT_MAX)){ + index = 0; + } + else if ((attr->index >= PORT1_TX_DISABLE) && (attr->index < PORT_TX_DISABLE_MAX)){ + index = 1; + } + if ((attr->index >= PORT1_RX_LOS) && (attr->index < PORT_RX_LOS_MAX)){ + index = 2; + } + + if(data->port == SFPPLUS_1_PORT_NUMBER) + val = (data->ddm->status[index] & BIT_INDEX(0)) ? 1 : 0; + else if(data->port == SFPPLUS_2_PORT_NUMBER) + val = (data->ddm->status[index] & BIT_INDEX(1)) ? 1 : 0; + else + val = (data->ddm->status[index] & BIT_INDEX(attr->index)) ? 1 : 0; + return sprintf(buf, "%d\n", val); +} + +static ssize_t qsfp_show_eeprom(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + char devfile[96]; + struct file *sfd; + int i2c_index = 0; + int result; + int offset[] = {SFP_CPLD_REG_ADDR_MODSELECT}; + int rdlen, rc; + mm_segment_t old_fs; + char buffer[256]; + + if (!sfp_is_port_present(client, attr->index)) { + return 0; + } + + snprintf(devfile, sizeof(devfile), "/sys/bus/i2c/devices/%d-0050/sfp_eeprom", portCPLDID_0[0]); + + /* Read SFP EEPROM */ + sfd = filp_open(devfile, O_RDONLY, 0); + if (IS_ERR(sfd)) { + dev_info(&client->dev, "Failed to open file(%s)#%d", devfile, __LINE__); + portCPLDID = portCPLDID_1; + sfpPlusID = sfpPlusID_1; + } + else{ + portCPLDID = portCPLDID_0; + sfpPlusID = sfpPlusID_0; + } + + if(strcmp(client->name, "sfpcpld33") == 0){ + if(attr->index == 0) + i2c_index = sfpPlusID[0]; + else if(attr->index == 1) + i2c_index = sfpPlusID[1]; + } + else{ + if(strcmp(client->name, "sfpcpld1") == 0) + i2c_index = portCPLDID[0]; + else if(strcmp(client->name, "sfpcpld9") == 0) + i2c_index = portCPLDID[1]; + else if(strcmp(client->name, "sfpcpld17") == 0) + i2c_index = portCPLDID[2]; + else if(strcmp(client->name, "sfpcpld25") == 0) + i2c_index = portCPLDID[3]; + + /* Port number is 1-8 */ + result = i2c_smbus_write_byte_data(client, offset[0], BIT_INDEX(attr->index)); + if (result < 0) { + dev_info(&client->dev, "%s, i2c_smbus_write_byte_data fail(%d)", __FUNCTION__, result); + } + } + + snprintf(devfile, sizeof(devfile), "/sys/bus/i2c/devices/%d-0050/sfp_eeprom", i2c_index); + + /* Read SFP EEPROM */ + sfd = filp_open(devfile, O_RDONLY, 0); + if (IS_ERR(sfd)) { + dev_info(&client->dev, "Failed to open file(%s)#%d", devfile, __LINE__); + return 0; + } + + if(!(sfd->f_op) || !(sfd->f_op->read) ) { + dev_info(&client->dev, "file %s cann't readable ?\n", devfile); + return 0; + } + + old_fs = get_fs(); + set_fs(KERNEL_DS); + rdlen = sfd->f_op->read(sfd, buffer, sizeof(buffer), &sfd->f_pos); + if (rdlen == 0) { + dev_info(&client->dev, "File(%s) empty!\n", devfile); + rc = 0; + goto exit; + } + + rc = sizeof(buffer); + memcpy(buf, buffer, rc); + + /* Reset module select register */ + if(strcmp(client->name, "sfpcpld33") != 0){ + /* Port number is 1-8 */ + result = i2c_smbus_write_byte_data(client, offset[0], 0); + if (result < 0) { + dev_info(&client->dev, "%s, i2c_smbus_write_byte_data fail(%d)", __FUNCTION__, result); + } + } + +exit: + set_fs(old_fs); + filp_close(sfd, 0); + + return rc; +} + +#if 0 +static ssize_t qsfp_set_eeprom(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + DEBUG_PRINT("data->port:%d attr index:%d", data->port, attr->index); + return 1; +} +#endif + +/* SFP/QSFP common attributes for sysfs */ +#define DECLARE_PORT_NUMBER_SENSOR_DEVICE_ATTR(PORT1, PORT2, PORT3, PORT4, PORT5, PORT6, PORT7, PORT8) \ + static SENSOR_DEVICE_ATTR(sfp##PORT1##_port_number, S_IRUGO, show_port_number, NULL, PORT##PORT1##_NUMBER); \ + static SENSOR_DEVICE_ATTR(sfp##PORT2##_port_number, S_IRUGO, show_port_number, NULL, PORT##PORT2##_NUMBER); \ + static SENSOR_DEVICE_ATTR(sfp##PORT3##_port_number, S_IRUGO, show_port_number, NULL, PORT##PORT3##_NUMBER); \ + static SENSOR_DEVICE_ATTR(sfp##PORT4##_port_number, S_IRUGO, show_port_number, NULL, PORT##PORT4##_NUMBER); \ + static SENSOR_DEVICE_ATTR(sfp##PORT5##_port_number, S_IRUGO, show_port_number, NULL, PORT##PORT5##_NUMBER); \ + static SENSOR_DEVICE_ATTR(sfp##PORT6##_port_number, S_IRUGO, show_port_number, NULL, PORT##PORT6##_NUMBER); \ + static SENSOR_DEVICE_ATTR(sfp##PORT7##_port_number, S_IRUGO, show_port_number, NULL, PORT##PORT7##_NUMBER); \ + static SENSOR_DEVICE_ATTR(sfp##PORT8##_port_number, S_IRUGO, show_port_number, NULL, PORT##PORT8##_NUMBER); +#define DECLARE_PORT_NUMBER_ATTR(PORT1, PORT2, PORT3, PORT4, PORT5, PORT6, PORT7, PORT8) \ + &sensor_dev_attr_sfp##PORT1##_port_number.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT2##_port_number.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT3##_port_number.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT4##_port_number.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT5##_port_number.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT6##_port_number.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT7##_port_number.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT8##_port_number.dev_attr.attr, +DECLARE_PORT_NUMBER_SENSOR_DEVICE_ATTR(1, 2, 3, 4, 5, 6, 7, 8) + +#define DECLARE_PORT_IS_PRESENT_SENSOR_DEVICE_ATTR(PORT1, PORT2, PORT3, PORT4, PORT5, PORT6, PORT7, PORT8) \ + static SENSOR_DEVICE_ATTR(sfp##PORT1##_is_present, S_IRUGO, show_present, NULL, PORT##PORT1##_PRESENT); \ + static SENSOR_DEVICE_ATTR(sfp##PORT2##_is_present, S_IRUGO, show_present, NULL, PORT##PORT2##_PRESENT); \ + static SENSOR_DEVICE_ATTR(sfp##PORT3##_is_present, S_IRUGO, show_present, NULL, PORT##PORT3##_PRESENT); \ + static SENSOR_DEVICE_ATTR(sfp##PORT4##_is_present, S_IRUGO, show_present, NULL, PORT##PORT4##_PRESENT); \ + static SENSOR_DEVICE_ATTR(sfp##PORT5##_is_present, S_IRUGO, show_present, NULL, PORT##PORT5##_PRESENT); \ + static SENSOR_DEVICE_ATTR(sfp##PORT6##_is_present, S_IRUGO, show_present, NULL, PORT##PORT6##_PRESENT); \ + static SENSOR_DEVICE_ATTR(sfp##PORT7##_is_present, S_IRUGO, show_present, NULL, PORT##PORT7##_PRESENT); \ + static SENSOR_DEVICE_ATTR(sfp##PORT8##_is_present, S_IRUGO, show_present, NULL, PORT##PORT8##_PRESENT); +#define DECLARE_PORT_IS_PRESENT_ATTR(PORT1, PORT2, PORT3, PORT4, PORT5, PORT6, PORT7, PORT8) \ + &sensor_dev_attr_sfp##PORT1##_is_present.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT2##_is_present.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT3##_is_present.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT4##_is_present.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT5##_is_present.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT6##_is_present.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT7##_is_present.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT8##_is_present.dev_attr.attr, +DECLARE_PORT_IS_PRESENT_SENSOR_DEVICE_ATTR(1, 2, 3, 4, 5, 6, 7, 8) + +#define DECLARE_PORT_TYPE_SENSOR_DEVICE_ATTR(PORT1, PORT2, PORT3, PORT4, PORT5, PORT6, PORT7, PORT8) \ + static SENSOR_DEVICE_ATTR(sfp##PORT1##_port_type, S_IRUGO, show_port_type, NULL, PORT##PORT1##_TYPE); \ + static SENSOR_DEVICE_ATTR(sfp##PORT2##_port_type, S_IRUGO, show_port_type, NULL, PORT##PORT2##_TYPE); \ + static SENSOR_DEVICE_ATTR(sfp##PORT3##_port_type, S_IRUGO, show_port_type, NULL, PORT##PORT3##_TYPE); \ + static SENSOR_DEVICE_ATTR(sfp##PORT4##_port_type, S_IRUGO, show_port_type, NULL, PORT##PORT4##_TYPE); \ + static SENSOR_DEVICE_ATTR(sfp##PORT5##_port_type, S_IRUGO, show_port_type, NULL, PORT##PORT5##_TYPE); \ + static SENSOR_DEVICE_ATTR(sfp##PORT6##_port_type, S_IRUGO, show_port_type, NULL, PORT##PORT6##_TYPE); \ + static SENSOR_DEVICE_ATTR(sfp##PORT7##_port_type, S_IRUGO, show_port_type, NULL, PORT##PORT7##_TYPE); \ + static SENSOR_DEVICE_ATTR(sfp##PORT8##_port_type, S_IRUGO, show_port_type, NULL, PORT##PORT8##_TYPE); +#define DECLARE_PORT_TYPE_ATTR(PORT1, PORT2, PORT3, PORT4, PORT5, PORT6, PORT7, PORT8) &sensor_dev_attr_sfp##PORT1##_port_type.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT2##_port_type.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT3##_port_type.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT4##_port_type.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT5##_port_type.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT6##_port_type.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT7##_port_type.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT8##_port_type.dev_attr.attr, +DECLARE_PORT_TYPE_SENSOR_DEVICE_ATTR(1, 2, 3, 4, 5, 6, 7, 8) + +#define DECLARE_PORT_RESET_SENSOR_DEVICE_ATTR(PORT1, PORT2, PORT3, PORT4, PORT5, PORT6, PORT7, PORT8) \ + static SENSOR_DEVICE_ATTR(sfp##PORT1##_port_reset, S_IWUSR | S_IRUGO, show_port_reset, sfp_set_port_reset, PORT##PORT1##_RESET); \ + static SENSOR_DEVICE_ATTR(sfp##PORT2##_port_reset, S_IWUSR | S_IRUGO, show_port_reset, sfp_set_port_reset, PORT##PORT2##_RESET); \ + static SENSOR_DEVICE_ATTR(sfp##PORT3##_port_reset, S_IWUSR | S_IRUGO, show_port_reset, sfp_set_port_reset, PORT##PORT3##_RESET); \ + static SENSOR_DEVICE_ATTR(sfp##PORT4##_port_reset, S_IWUSR | S_IRUGO, show_port_reset, sfp_set_port_reset, PORT##PORT4##_RESET); \ + static SENSOR_DEVICE_ATTR(sfp##PORT5##_port_reset, S_IWUSR | S_IRUGO, show_port_reset, sfp_set_port_reset, PORT##PORT5##_RESET); \ + static SENSOR_DEVICE_ATTR(sfp##PORT6##_port_reset, S_IWUSR | S_IRUGO, show_port_reset, sfp_set_port_reset, PORT##PORT6##_RESET); \ + static SENSOR_DEVICE_ATTR(sfp##PORT7##_port_reset, S_IWUSR | S_IRUGO, show_port_reset, sfp_set_port_reset, PORT##PORT7##_RESET); \ + static SENSOR_DEVICE_ATTR(sfp##PORT8##_port_reset, S_IWUSR | S_IRUGO, show_port_reset, sfp_set_port_reset, PORT##PORT8##_RESET); +#define DECLARE_PORT_RESET_ATTR(PORT1, PORT2, PORT3, PORT4, PORT5, PORT6, PORT7, PORT8) &sensor_dev_attr_sfp##PORT1##_port_reset.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT2##_port_reset.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT3##_port_reset.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT4##_port_reset.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT5##_port_reset.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT6##_port_reset.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT7##_port_reset.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT8##_port_reset.dev_attr.attr, +DECLARE_PORT_RESET_SENSOR_DEVICE_ATTR(1, 2, 3, 4, 5, 6, 7, 8) + +/* QSFP attributes for sysfs */ +#define DECLARE_PORT_RX_LOSn_SENSOR_DEVICE_ATTR(INDEX, PORT1, PORT2, PORT3, PORT4, PORT5, PORT6, PORT7, PORT8) \ + static SENSOR_DEVICE_ATTR(sfp##PORT1##_rx_los##INDEX, S_IRUGO, qsfp_show_tx_rx_status, NULL, PORT##PORT1##_RX_LOS##INDEX); \ + static SENSOR_DEVICE_ATTR(sfp##PORT2##_rx_los##INDEX, S_IRUGO, qsfp_show_tx_rx_status, NULL, PORT##PORT2##_RX_LOS##INDEX); \ + static SENSOR_DEVICE_ATTR(sfp##PORT3##_rx_los##INDEX, S_IRUGO, qsfp_show_tx_rx_status, NULL, PORT##PORT3##_RX_LOS##INDEX); \ + static SENSOR_DEVICE_ATTR(sfp##PORT4##_rx_los##INDEX, S_IRUGO, qsfp_show_tx_rx_status, NULL, PORT##PORT4##_RX_LOS##INDEX); \ + static SENSOR_DEVICE_ATTR(sfp##PORT5##_rx_los##INDEX, S_IRUGO, qsfp_show_tx_rx_status, NULL, PORT##PORT5##_RX_LOS##INDEX); \ + static SENSOR_DEVICE_ATTR(sfp##PORT6##_rx_los##INDEX, S_IRUGO, qsfp_show_tx_rx_status, NULL, PORT##PORT6##_RX_LOS##INDEX); \ + static SENSOR_DEVICE_ATTR(sfp##PORT7##_rx_los##INDEX, S_IRUGO, qsfp_show_tx_rx_status, NULL, PORT##PORT7##_RX_LOS##INDEX); \ + static SENSOR_DEVICE_ATTR(sfp##PORT8##_rx_los##INDEX, S_IRUGO, qsfp_show_tx_rx_status, NULL, PORT##PORT8##_RX_LOS##INDEX); +#define DECLARE_PORT_RX_LOSn_ATTR(INDEX, PORT1, PORT2, PORT3, PORT4, PORT5, PORT6, PORT7, PORT8) \ + &sensor_dev_attr_sfp##PORT1##_rx_los##INDEX.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT2##_rx_los##INDEX.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT3##_rx_los##INDEX.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT4##_rx_los##INDEX.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT5##_rx_los##INDEX.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT6##_rx_los##INDEX.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT7##_rx_los##INDEX.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT8##_rx_los##INDEX.dev_attr.attr, +DECLARE_PORT_RX_LOSn_SENSOR_DEVICE_ATTR(1, 1, 2, 3, 4, 5, 6, 7, 8) +DECLARE_PORT_RX_LOSn_SENSOR_DEVICE_ATTR(2, 1, 2, 3, 4, 5, 6, 7, 8) +DECLARE_PORT_RX_LOSn_SENSOR_DEVICE_ATTR(3, 1, 2, 3, 4, 5, 6, 7, 8) +DECLARE_PORT_RX_LOSn_SENSOR_DEVICE_ATTR(4, 1, 2, 3, 4, 5, 6, 7, 8) + +#define DECLARE_PORT_TX_DISABLEn_SENSOR_DEVICE_ATTR(INDEX, PORT1, PORT2, PORT3, PORT4, PORT5, PORT6, PORT7, PORT8) \ + static SENSOR_DEVICE_ATTR(sfp##PORT1##_tx_disable##INDEX, S_IWUSR | S_IRUGO, qsfp_show_tx_rx_status, qsfp_set_tx_disable, PORT##PORT1##_TX_DISABLE##INDEX); \ + static SENSOR_DEVICE_ATTR(sfp##PORT2##_tx_disable##INDEX, S_IWUSR | S_IRUGO, qsfp_show_tx_rx_status, qsfp_set_tx_disable, PORT##PORT2##_TX_DISABLE##INDEX); \ + static SENSOR_DEVICE_ATTR(sfp##PORT3##_tx_disable##INDEX, S_IWUSR | S_IRUGO, qsfp_show_tx_rx_status, qsfp_set_tx_disable, PORT##PORT3##_TX_DISABLE##INDEX); \ + static SENSOR_DEVICE_ATTR(sfp##PORT4##_tx_disable##INDEX, S_IWUSR | S_IRUGO, qsfp_show_tx_rx_status, qsfp_set_tx_disable, PORT##PORT4##_TX_DISABLE##INDEX); \ + static SENSOR_DEVICE_ATTR(sfp##PORT5##_tx_disable##INDEX, S_IWUSR | S_IRUGO, qsfp_show_tx_rx_status, qsfp_set_tx_disable, PORT##PORT5##_TX_DISABLE##INDEX); \ + static SENSOR_DEVICE_ATTR(sfp##PORT6##_tx_disable##INDEX, S_IWUSR | S_IRUGO, qsfp_show_tx_rx_status, qsfp_set_tx_disable, PORT##PORT6##_TX_DISABLE##INDEX); \ + static SENSOR_DEVICE_ATTR(sfp##PORT7##_tx_disable##INDEX, S_IWUSR | S_IRUGO, qsfp_show_tx_rx_status, qsfp_set_tx_disable, PORT##PORT7##_TX_DISABLE##INDEX); \ + static SENSOR_DEVICE_ATTR(sfp##PORT8##_tx_disable##INDEX, S_IWUSR | S_IRUGO, qsfp_show_tx_rx_status, qsfp_set_tx_disable, PORT##PORT8##_TX_DISABLE##INDEX); + +#define DECLARE_PORT_TX_DISABLEn_ATTR(INDEX, PORT1, PORT2, PORT3, PORT4, PORT5, PORT6, PORT7, PORT8) \ + &sensor_dev_attr_sfp##PORT1##_tx_disable##INDEX.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT2##_tx_disable##INDEX.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT3##_tx_disable##INDEX.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT4##_tx_disable##INDEX.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT5##_tx_disable##INDEX.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT6##_tx_disable##INDEX.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT7##_tx_disable##INDEX.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT8##_tx_disable##INDEX.dev_attr.attr, +DECLARE_PORT_TX_DISABLEn_SENSOR_DEVICE_ATTR(1, 1, 2, 3, 4, 5, 6, 7, 8) +DECLARE_PORT_TX_DISABLEn_SENSOR_DEVICE_ATTR(2, 1, 2, 3, 4, 5, 6, 7, 8) +DECLARE_PORT_TX_DISABLEn_SENSOR_DEVICE_ATTR(3, 1, 2, 3, 4, 5, 6, 7, 8) +DECLARE_PORT_TX_DISABLEn_SENSOR_DEVICE_ATTR(4, 1, 2, 3, 4, 5, 6, 7, 8) + +#define DECLARE_PORT_TX_FAULTn_SENSOR_DEVICE_ATTR(INDEX, PORT1, PORT2, PORT3, PORT4, PORT5, PORT6, PORT7, PORT8) \ + static SENSOR_DEVICE_ATTR(sfp##PORT1##_tx_fault##INDEX, S_IRUGO, qsfp_show_tx_rx_status, NULL, PORT##PORT1##_TX_FAULT##INDEX); \ + static SENSOR_DEVICE_ATTR(sfp##PORT2##_tx_fault##INDEX, S_IRUGO, qsfp_show_tx_rx_status, NULL, PORT##PORT2##_TX_FAULT##INDEX); \ + static SENSOR_DEVICE_ATTR(sfp##PORT3##_tx_fault##INDEX, S_IRUGO, qsfp_show_tx_rx_status, NULL, PORT##PORT3##_TX_FAULT##INDEX); \ + static SENSOR_DEVICE_ATTR(sfp##PORT4##_tx_fault##INDEX, S_IRUGO, qsfp_show_tx_rx_status, NULL, PORT##PORT4##_TX_FAULT##INDEX); \ + static SENSOR_DEVICE_ATTR(sfp##PORT5##_tx_fault##INDEX, S_IRUGO, qsfp_show_tx_rx_status, NULL, PORT##PORT5##_TX_FAULT##INDEX); \ + static SENSOR_DEVICE_ATTR(sfp##PORT6##_tx_fault##INDEX, S_IRUGO, qsfp_show_tx_rx_status, NULL, PORT##PORT6##_TX_FAULT##INDEX); \ + static SENSOR_DEVICE_ATTR(sfp##PORT7##_tx_fault##INDEX, S_IRUGO, qsfp_show_tx_rx_status, NULL, PORT##PORT7##_TX_FAULT##INDEX); \ + static SENSOR_DEVICE_ATTR(sfp##PORT8##_tx_fault##INDEX, S_IRUGO, qsfp_show_tx_rx_status, NULL, PORT##PORT8##_TX_FAULT##INDEX); +#define DECLARE_PORT_TX_FAULTn_ATTR(INDEX, PORT1, PORT2, PORT3, PORT4, PORT5, PORT6, PORT7, PORT8) \ + &sensor_dev_attr_sfp##PORT1##_tx_fault##INDEX.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT2##_tx_fault##INDEX.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT3##_tx_fault##INDEX.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT4##_tx_fault##INDEX.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT5##_tx_fault##INDEX.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT6##_tx_fault##INDEX.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT7##_tx_fault##INDEX.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT8##_tx_fault##INDEX.dev_attr.attr, +DECLARE_PORT_TX_FAULTn_SENSOR_DEVICE_ATTR(1, 1, 2, 3, 4, 5, 6, 7, 8) +DECLARE_PORT_TX_FAULTn_SENSOR_DEVICE_ATTR(2, 1, 2, 3, 4, 5, 6, 7, 8) +DECLARE_PORT_TX_FAULTn_SENSOR_DEVICE_ATTR(3, 1, 2, 3, 4, 5, 6, 7, 8) +DECLARE_PORT_TX_FAULTn_SENSOR_DEVICE_ATTR(4, 1, 2, 3, 4, 5, 6, 7, 8) + +#define DECLARE_PORT_LED_DEVICE_ATTR() \ + static SENSOR_DEVICE_ATTR(sfp_led_disable, S_IWUSR | S_IRUGO, qsfp_show_port_led, qsfp_set_port_led, PORT_LED); +#define DECLARE_PORT_LED_ATTR() \ + &sensor_dev_attr_sfp_led_disable.dev_attr.attr, +DECLARE_PORT_LED_DEVICE_ATTR() + +#define DECLARE_PORT_EEPROMn_SENSOR_DEVICE_ATTR(PORT1, PORT2, PORT3, PORT4, PORT5, PORT6, PORT7, PORT8) \ + static SENSOR_DEVICE_ATTR(sfp##PORT1##_eeprom, S_IRUGO, qsfp_show_eeprom, NULL, PORT##PORT1##_EEPROM); \ + static SENSOR_DEVICE_ATTR(sfp##PORT2##_eeprom, S_IRUGO, qsfp_show_eeprom, NULL, PORT##PORT2##_EEPROM); \ + static SENSOR_DEVICE_ATTR(sfp##PORT3##_eeprom, S_IRUGO, qsfp_show_eeprom, NULL, PORT##PORT3##_EEPROM); \ + static SENSOR_DEVICE_ATTR(sfp##PORT4##_eeprom, S_IRUGO, qsfp_show_eeprom, NULL, PORT##PORT4##_EEPROM); \ + static SENSOR_DEVICE_ATTR(sfp##PORT5##_eeprom, S_IRUGO, qsfp_show_eeprom, NULL, PORT##PORT5##_EEPROM); \ + static SENSOR_DEVICE_ATTR(sfp##PORT6##_eeprom, S_IRUGO, qsfp_show_eeprom, NULL, PORT##PORT6##_EEPROM); \ + static SENSOR_DEVICE_ATTR(sfp##PORT7##_eeprom, S_IRUGO, qsfp_show_eeprom, NULL, PORT##PORT7##_EEPROM); \ + static SENSOR_DEVICE_ATTR(sfp##PORT8##_eeprom, S_IRUGO, qsfp_show_eeprom, NULL, PORT##PORT8##_EEPROM); +#define DECLARE_PORT_EEPROMTn_ATTR(PORT1, PORT2, PORT3, PORT4, PORT5, PORT6, PORT7, PORT8) \ + &sensor_dev_attr_sfp##PORT1##_eeprom.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT2##_eeprom.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT3##_eeprom.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT4##_eeprom.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT5##_eeprom.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT6##_eeprom.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT7##_eeprom.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT8##_eeprom.dev_attr.attr, +DECLARE_PORT_EEPROMn_SENSOR_DEVICE_ATTR(1, 2, 3, 4, 5, 6, 7, 8) + +#define DECLARE_PORT_LPMODE_SENSOR_DEVICE_ATTR(PORT1, PORT2, PORT3, PORT4, PORT5, PORT6, PORT7, PORT8) \ + static SENSOR_DEVICE_ATTR(sfp##PORT1##_lpmode, S_IWUSR | S_IRUGO, qsfp_show_port_lpmode, qsfp_set_port_lpmode, PORT##PORT1##_LPMODE); \ + static SENSOR_DEVICE_ATTR(sfp##PORT2##_lpmode, S_IWUSR | S_IRUGO, qsfp_show_port_lpmode, qsfp_set_port_lpmode, PORT##PORT2##_LPMODE); \ + static SENSOR_DEVICE_ATTR(sfp##PORT3##_lpmode, S_IWUSR | S_IRUGO, qsfp_show_port_lpmode, qsfp_set_port_lpmode, PORT##PORT3##_LPMODE); \ + static SENSOR_DEVICE_ATTR(sfp##PORT4##_lpmode, S_IWUSR | S_IRUGO, qsfp_show_port_lpmode, qsfp_set_port_lpmode, PORT##PORT4##_LPMODE); \ + static SENSOR_DEVICE_ATTR(sfp##PORT5##_lpmode, S_IWUSR | S_IRUGO, qsfp_show_port_lpmode, qsfp_set_port_lpmode, PORT##PORT5##_LPMODE); \ + static SENSOR_DEVICE_ATTR(sfp##PORT6##_lpmode, S_IWUSR | S_IRUGO, qsfp_show_port_lpmode, qsfp_set_port_lpmode, PORT##PORT6##_LPMODE); \ + static SENSOR_DEVICE_ATTR(sfp##PORT7##_lpmode, S_IWUSR | S_IRUGO, qsfp_show_port_lpmode, qsfp_set_port_lpmode, PORT##PORT7##_LPMODE); \ + static SENSOR_DEVICE_ATTR(sfp##PORT8##_lpmode, S_IWUSR | S_IRUGO, qsfp_show_port_lpmode, qsfp_set_port_lpmode, PORT##PORT8##_LPMODE); +#define DECLARE_PORT_LPMODE_ATTR(PORT1, PORT2, PORT3, PORT4, PORT5, PORT6, PORT7, PORT8) \ + &sensor_dev_attr_sfp##PORT1##_lpmode.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT2##_lpmode.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT3##_lpmode.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT4##_lpmode.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT5##_lpmode.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT6##_lpmode.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT7##_lpmode.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT8##_lpmode.dev_attr.attr, +DECLARE_PORT_LPMODE_SENSOR_DEVICE_ATTR(1, 2, 3, 4, 5, 6, 7, 8) + +#define DECLARE_PORT_CPLD_REVISION() \ + static SENSOR_DEVICE_ATTR(cpld_revision, (0660), show_cpld_version, NULL, CPLD_REVISION); +#define DECLARE_PORT_CPLD_REVISION_ATTR() \ + &sensor_dev_attr_cpld_revision.dev_attr.attr, +DECLARE_PORT_CPLD_REVISION() + +static struct attribute *qsfp_attributes[] = { + DECLARE_PORT_NUMBER_ATTR(1, 2, 3, 4, 5, 6, 7, 8) + DECLARE_PORT_TYPE_ATTR(1, 2, 3, 4, 5, 6, 7, 8) + DECLARE_PORT_IS_PRESENT_ATTR(1, 2, 3, 4, 5, 6, 7, 8) + DECLARE_PORT_RESET_ATTR(1, 2, 3, 4, 5, 6, 7, 8) + DECLARE_PORT_LPMODE_ATTR(1, 2, 3, 4, 5, 6, 7, 8) + DECLARE_PORT_LED_ATTR() + DECLARE_PORT_RX_LOSn_ATTR(1, 1, 2, 3, 4, 5, 6, 7, 8) + DECLARE_PORT_RX_LOSn_ATTR(2, 1, 2, 3, 4, 5, 6, 7, 8) + DECLARE_PORT_RX_LOSn_ATTR(3, 1, 2, 3, 4, 5, 6, 7, 8) + DECLARE_PORT_RX_LOSn_ATTR(4, 1, 2, 3, 4, 5, 6, 7, 8) + DECLARE_PORT_TX_DISABLEn_ATTR(1, 1, 2, 3, 4, 5, 6, 7, 8) + DECLARE_PORT_TX_DISABLEn_ATTR(2, 1, 2, 3, 4, 5, 6, 7, 8) + DECLARE_PORT_TX_DISABLEn_ATTR(3, 1, 2, 3, 4, 5, 6, 7, 8) + DECLARE_PORT_TX_DISABLEn_ATTR(4, 1, 2, 3, 4, 5, 6, 7, 8) + DECLARE_PORT_TX_FAULTn_ATTR(1, 1, 2, 3, 4, 5, 6, 7, 8) + DECLARE_PORT_TX_FAULTn_ATTR(2, 1, 2, 3, 4, 5, 6, 7, 8) + DECLARE_PORT_TX_FAULTn_ATTR(3, 1, 2, 3, 4, 5, 6, 7, 8) + DECLARE_PORT_TX_FAULTn_ATTR(4, 1, 2, 3, 4, 5, 6, 7, 8) + DECLARE_PORT_EEPROMTn_ATTR(1, 2, 3, 4, 5, 6, 7, 8) + DECLARE_PORT_CPLD_REVISION_ATTR() + NULL +}; + + +/* SFP msa attributes for sysfs */ +static struct attribute *sfp_msa_attributes[] = { + DECLARE_PORT_NUMBER_ATTR(1, 2, 3, 4, 5, 6, 7, 8) + DECLARE_PORT_TYPE_ATTR(1, 2, 3, 4, 5, 6, 7, 8) + DECLARE_PORT_IS_PRESENT_ATTR(1, 2, 3, 4, 5, 6, 7, 8) + DECLARE_PORT_RESET_ATTR(1, 2, 3, 4, 5, 6, 7, 8) + NULL +}; + +/* SFP ddm attributes for sysfs */ +#define DECLARE_RX_LOS_SENSOR_DEVICE_ATTR(PORT1, PORT2, PORT3, PORT4, PORT5, PORT6, PORT7, PORT8) \ + static SENSOR_DEVICE_ATTR(sfp##PORT1##_rx_los, S_IRUGO, sfp_show_tx_rx_status, NULL, PORT##PORT1##_RX_LOS); \ + static SENSOR_DEVICE_ATTR(sfp##PORT2##_rx_los, S_IRUGO, sfp_show_tx_rx_status, NULL, PORT##PORT2##_RX_LOS); \ + static SENSOR_DEVICE_ATTR(sfp##PORT3##_rx_los, S_IRUGO, sfp_show_tx_rx_status, NULL, PORT##PORT3##_RX_LOS); \ + static SENSOR_DEVICE_ATTR(sfp##PORT4##_rx_los, S_IRUGO, sfp_show_tx_rx_status, NULL, PORT##PORT4##_RX_LOS); \ + static SENSOR_DEVICE_ATTR(sfp##PORT5##_rx_los, S_IRUGO, sfp_show_tx_rx_status, NULL, PORT##PORT5##_RX_LOS); \ + static SENSOR_DEVICE_ATTR(sfp##PORT6##_rx_los, S_IRUGO, sfp_show_tx_rx_status, NULL, PORT##PORT6##_RX_LOS); \ + static SENSOR_DEVICE_ATTR(sfp##PORT7##_rx_los, S_IRUGO, sfp_show_tx_rx_status, NULL, PORT##PORT7##_RX_LOS); \ + static SENSOR_DEVICE_ATTR(sfp##PORT8##_rx_los, S_IRUGO, sfp_show_tx_rx_status, NULL, PORT##PORT8##_RX_LOS); +#define DECLARE_RX_LOS_ATTR(PORT1, PORT2, PORT3, PORT4, PORT5, PORT6, PORT7, PORT8) &sensor_dev_attr_sfp##PORT1##_rx_los.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT2##_rx_los.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT3##_rx_los.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT4##_rx_los.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT5##_rx_los.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT6##_rx_los.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT7##_rx_los.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT8##_rx_los.dev_attr.attr, +DECLARE_RX_LOS_SENSOR_DEVICE_ATTR(1, 2, 3, 4, 5, 6, 7, 8) + +#define DECLARE_TX_DISABLE_SENSOR_DEVICE_ATTR(PORT1, PORT2, PORT3, PORT4, PORT5, PORT6, PORT7, PORT8) \ + static SENSOR_DEVICE_ATTR(sfp##PORT1##_tx_disable, S_IWUSR | S_IRUGO, sfp_show_tx_rx_status, sfp_set_tx_disable, PORT##PORT1##_TX_DISABLE); \ + static SENSOR_DEVICE_ATTR(sfp##PORT2##_tx_disable, S_IWUSR | S_IRUGO, sfp_show_tx_rx_status, sfp_set_tx_disable, PORT##PORT2##_TX_DISABLE); \ + static SENSOR_DEVICE_ATTR(sfp##PORT3##_tx_disable, S_IWUSR | S_IRUGO, sfp_show_tx_rx_status, sfp_set_tx_disable, PORT##PORT3##_TX_DISABLE); \ + static SENSOR_DEVICE_ATTR(sfp##PORT4##_tx_disable, S_IWUSR | S_IRUGO, sfp_show_tx_rx_status, sfp_set_tx_disable, PORT##PORT4##_TX_DISABLE); \ + static SENSOR_DEVICE_ATTR(sfp##PORT5##_tx_disable, S_IWUSR | S_IRUGO, sfp_show_tx_rx_status, sfp_set_tx_disable, PORT##PORT5##_TX_DISABLE); \ + static SENSOR_DEVICE_ATTR(sfp##PORT6##_tx_disable, S_IWUSR | S_IRUGO, sfp_show_tx_rx_status, sfp_set_tx_disable, PORT##PORT6##_TX_DISABLE); \ + static SENSOR_DEVICE_ATTR(sfp##PORT7##_tx_disable, S_IWUSR | S_IRUGO, sfp_show_tx_rx_status, sfp_set_tx_disable, PORT##PORT7##_TX_DISABLE); \ + static SENSOR_DEVICE_ATTR(sfp##PORT8##_tx_disable, S_IWUSR | S_IRUGO, sfp_show_tx_rx_status, sfp_set_tx_disable, PORT##PORT8##_TX_DISABLE); +#define DECLARE_TX_DISABLE_ATTR(PORT1, PORT2, PORT3, PORT4, PORT5, PORT6, PORT7, PORT8) \ + &sensor_dev_attr_sfp##PORT1##_tx_disable.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT2##_tx_disable.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT3##_tx_disable.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT4##_tx_disable.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT5##_tx_disable.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT6##_tx_disable.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT7##_tx_disable.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT8##_tx_disable.dev_attr.attr, +DECLARE_TX_DISABLE_SENSOR_DEVICE_ATTR(1, 2, 3, 4, 5, 6, 7, 8) + +#define DECLARE_TX_FAULT_SENSOR_DEVICE_ATTR(PORT1, PORT2, PORT3, PORT4, PORT5, PORT6, PORT7, PORT8) \ + static SENSOR_DEVICE_ATTR(sfp##PORT1##_tx_fault, S_IRUGO, sfp_show_tx_rx_status, NULL, PORT##PORT1##_TX_FAULT); \ + static SENSOR_DEVICE_ATTR(sfp##PORT2##_tx_fault, S_IRUGO, sfp_show_tx_rx_status, NULL, PORT##PORT2##_TX_FAULT); \ + static SENSOR_DEVICE_ATTR(sfp##PORT3##_tx_fault, S_IRUGO, sfp_show_tx_rx_status, NULL, PORT##PORT3##_TX_FAULT); \ + static SENSOR_DEVICE_ATTR(sfp##PORT4##_tx_fault, S_IRUGO, sfp_show_tx_rx_status, NULL, PORT##PORT4##_TX_FAULT); \ + static SENSOR_DEVICE_ATTR(sfp##PORT5##_tx_fault, S_IRUGO, sfp_show_tx_rx_status, NULL, PORT##PORT5##_TX_FAULT); \ + static SENSOR_DEVICE_ATTR(sfp##PORT6##_tx_fault, S_IRUGO, sfp_show_tx_rx_status, NULL, PORT##PORT6##_TX_FAULT); \ + static SENSOR_DEVICE_ATTR(sfp##PORT7##_tx_fault, S_IRUGO, sfp_show_tx_rx_status, NULL, PORT##PORT7##_TX_FAULT); \ + static SENSOR_DEVICE_ATTR(sfp##PORT8##_tx_fault, S_IRUGO, sfp_show_tx_rx_status, NULL, PORT##PORT8##_TX_FAULT); +#define DECLARE_TX_FAULT_ATTR(PORT1, PORT2, PORT3, PORT4, PORT5, PORT6, PORT7, PORT8) \ + &sensor_dev_attr_sfp##PORT1##_tx_fault.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT2##_tx_fault.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT3##_tx_fault.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT4##_tx_fault.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT5##_tx_fault.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT6##_tx_fault.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT7##_tx_fault.dev_attr.attr, \ + &sensor_dev_attr_sfp##PORT8##_tx_fault.dev_attr.attr, +DECLARE_TX_FAULT_SENSOR_DEVICE_ATTR(1, 2, 3, 4, 5, 6, 7, 8) +static struct attribute *sfp_ddm_attributes[] = { + DECLARE_RX_LOS_ATTR(1, 2, 3, 4, 5, 6, 7, 8) + DECLARE_TX_DISABLE_ATTR(1, 2, 3, 4, 5, 6, 7, 8) + DECLARE_TX_FAULT_ATTR(1, 2, 3, 4, 5, 6, 7, 8) + NULL +}; + +static ssize_t sfp_eeprom_write(struct i2c_client *client, u8 command, const char *data, + int data_len) +{ +#if USE_I2C_BLOCK_READ + int result, retry = I2C_RW_RETRY_COUNT; + + if (data_len > I2C_SMBUS_BLOCK_MAX) { + data_len = I2C_SMBUS_BLOCK_MAX; + } + + while (retry) { + result = i2c_smbus_write_i2c_block_data(client, command, data_len, data); + if (result < 0) { + msleep(I2C_RW_RETRY_INTERVAL); + retry--; + continue; + } + + break; + } + + if (unlikely(result < 0)) { + return result; + } + + return data_len; +#else + int result, retry = I2C_RW_RETRY_COUNT; + + while (retry) { + result = i2c_smbus_write_byte_data(client, command, *data); + if (result < 0) { + msleep(I2C_RW_RETRY_INTERVAL); + retry--; + continue; + } + + break; + } + + if (unlikely(result < 0)) { + return result; + } + + return 1; +#endif + +} + + +static ssize_t sfp_port_write(struct sfp_port_data *data, + const char *buf, loff_t off, size_t count) +{ + ssize_t retval = 0; + + if (unlikely(!count)) { + return count; + } + + /* + * Write data to chip, protecting against concurrent updates + * from this host, but not from other I2C masters. + */ + mutex_lock(&data->update_lock); + + while (count) { + ssize_t status; + + status = sfp_eeprom_write(data->client, off, buf, count); + if (status <= 0) { + if (retval == 0) { + retval = status; + } + break; + } + buf += status; + off += status; + count -= status; + retval += status; + } + + mutex_unlock(&data->update_lock); + return retval; +} + + +static ssize_t sfp_bin_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, + char *buf, loff_t off, size_t count) +{ + struct sfp_port_data *data; + DEBUG_PRINT("offset = (%d), count = (%d)", (int)off, (int)count); + data = dev_get_drvdata(container_of(kobj, struct device, kobj)); + return sfp_port_write(data, buf, off, count); +} + +static ssize_t sfp_eeprom_read(struct i2c_client *client, u8 command, u8 *data, + int data_len) +{ +#if USE_I2C_BLOCK_READ + int result, retry = I2C_RW_RETRY_COUNT; + + if (data_len > I2C_SMBUS_BLOCK_MAX) { + data_len = I2C_SMBUS_BLOCK_MAX; + } + + while (retry) { + result = i2c_smbus_read_i2c_block_data(client, command, data_len, data); + if (result < 0) { + msleep(I2C_RW_RETRY_INTERVAL); + retry--; + continue; + } + + break; + } + + if (unlikely(result < 0)) + goto abort; + if (unlikely(result != data_len)) { + result = -EIO; + goto abort; + } + + /* result = data_len; */ + +abort: + return result; +#else + int result, retry = I2C_RW_RETRY_COUNT; + + while (retry) { + result = i2c_smbus_read_byte_data(client, command); + if (result < 0) { + msleep(I2C_RW_RETRY_INTERVAL); + retry--; + continue; + } + + break; + } + + if (unlikely(result < 0)) { + dev_dbg(&client->dev, "sfp read byte data failed, command(0x%2x), data(0x%2x)\r\n", command, result); + goto abort; + } + + *data = (u8)result; + result = 1; + +abort: + return result; +#endif +} + +static ssize_t sfp_port_read(struct sfp_port_data *data, + char *buf, loff_t off, size_t count) +{ + ssize_t retval = 0; + + if (unlikely(!count)) { + DEBUG_PRINT("Count = 0, return"); + return count; + } + + /* + * Read data from chip, protecting against concurrent updates + * from this host, but not from other I2C masters. + */ + mutex_lock(&data->update_lock); + + while (count) { + ssize_t status; + + status = sfp_eeprom_read(data->client, off, buf, count); + if (status <= 0) { + if (retval == 0) { + retval = status; + } + break; + } + + buf += status; + off += status; + count -= status; + retval += status; + } + + mutex_unlock(&data->update_lock); + return retval; + +} + +static ssize_t sfp_bin_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, + char *buf, loff_t off, size_t count) +{ + struct sfp_port_data *data; + DEBUG_PRINT("offset = (%d), count = (%d)", (int)off, (int)count); + data = dev_get_drvdata(container_of(kobj, struct device, kobj)); + return sfp_port_read(data, buf, off, count); +} + +static int sfp_sysfs_eeprom_init(struct kobject *kobj, struct bin_attribute *eeprom) +{ + int err; + + sysfs_bin_attr_init(eeprom); + eeprom->attr.name = EEPROM_NAME; + eeprom->attr.mode = S_IWUSR | S_IRUGO; + eeprom->read = sfp_bin_read; + eeprom->write = sfp_bin_write; + eeprom->size = EEPROM_SIZE; + + /* Create eeprom file */ + err = sysfs_create_bin_file(kobj, eeprom); + if (err) { + return err; + } + + return 0; +} + +static int sfp_sysfs_eeprom_cleanup(struct kobject *kobj, struct bin_attribute *eeprom) +{ + sysfs_remove_bin_file(kobj, eeprom); + return 0; +} + +static const struct attribute_group sfp_msa_group = { + .attrs = sfp_msa_attributes, +}; + +static int sfp_i2c_check_functionality(struct i2c_client *client) +{ +#if USE_I2C_BLOCK_READ + return i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK); +#else + return i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA); +#endif +} + +static int sfp_msa_probe(struct i2c_client *client, const struct i2c_device_id *dev_id, + struct sfp_msa_data **data) +{ + int status; + struct sfp_msa_data *msa; + + if (!sfp_i2c_check_functionality(client)) { + status = -EIO; + goto exit; + } + + msa = kzalloc(sizeof(struct sfp_msa_data), GFP_KERNEL); + if (!msa) { + status = -ENOMEM; + goto exit; + } + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &sfp_msa_group); + if (status) { + goto exit_free; + } + + /* init eeprom */ + status = sfp_sysfs_eeprom_init(&client->dev.kobj, &msa->eeprom.bin); + if (status) { + dev_info(&client->dev, "sfp msa '%s' (sfp_sysfs_eeprom_init fail...)\n", client->name); + /* goto exit_remove; */ + } + + *data = msa; + dev_info(&client->dev, "sfp msa '%s'\n", client->name); + + return 0; + +/* exit_remove: */ + sysfs_remove_group(&client->dev.kobj, &sfp_msa_group); +exit_free: + kfree(msa); +exit: + + return status; +} + +static const struct attribute_group sfp_ddm_group = { + .attrs = sfp_ddm_attributes, +}; + +static int sfp_ddm_probe(struct i2c_client *client, const struct i2c_device_id *dev_id, + struct sfp_ddm_data **data) +{ + int status; + struct sfp_ddm_data *ddm; + + if (!sfp_i2c_check_functionality(client)) { + status = -EIO; + goto exit; + } + + ddm = kzalloc(sizeof(struct sfp_ddm_data), GFP_KERNEL); + if (!ddm) { + status = -ENOMEM; + goto exit; + } + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &sfp_ddm_group); + if (status) { + goto exit_free; + } + + /* init eeprom */ + status = sfp_sysfs_eeprom_init(&client->dev.kobj, &ddm->eeprom.bin); + if (status) { + goto exit_remove; + } + + *data = ddm; + dev_info(&client->dev, "sfp ddm '%s'\n", client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &sfp_ddm_group); +exit_free: + kfree(ddm); +exit: + + return status; +} + +static const struct attribute_group qsfp_group = { + .attrs = qsfp_attributes, +}; + +static int qsfp_probe(struct i2c_client *client, const struct i2c_device_id *dev_id, + struct qsfp_data **data) +{ + int status; + struct qsfp_data *qsfp; + struct sfp_port_data *port_data = i2c_get_clientdata(client); + + + if (!sfp_i2c_check_functionality(client)) { + status = -EIO; + goto exit; + } + + qsfp = kzalloc(sizeof(struct qsfp_data), GFP_KERNEL); + if (!qsfp) { + status = -ENOMEM; + goto exit; + } + + /* Register sysfs hooks */ + if ( ((port_data->port < SFPPLUS_1_PORT_NUMBER) && (client->addr == SFP_CPLD_I2C_ADDR)) || + ((port_data->port >= SFPPLUS_1_PORT_NUMBER) && (client->addr == SFP_EEPROM_A0_I2C_ADDR)) ) + { + status = sysfs_create_group(&client->dev.kobj, &qsfp_group); + if (status) { + goto exit_free; + } + } + + if (client->addr == SFP_EEPROM_A0_I2C_ADDR){ + /* init eeprom */ + status = sfp_sysfs_eeprom_init(&client->dev.kobj, &qsfp->eeprom.bin); + if (status) { + goto exit_remove; + } + } + + /* Bring QSFPs out of reset */ + + *data = qsfp; + dev_info(&client->dev, "qsfp '%s'\n", client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &qsfp_group); +exit_free: + kfree(qsfp); +exit: + + return status; +} + +static int sfp_device_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + struct sfp_port_data *data = NULL; + + data = kzalloc(sizeof(struct sfp_port_data), GFP_KERNEL); + if (!data) { + return -ENOMEM; + } + + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); + data->port = dev_id->driver_data; + data->client = client; + + DEBUG_PRINT("data->port:%d client->addr:0x%0x\n", data->port, client->addr); + if (client->addr == SFP_CPLD_I2C_ADDR){ + if(data->port >= SFPPLUS_1_PORT_NUMBER){ + DEBUG_PRINT("client->addr:0x%0x\n", client->addr); + return -ENODEV; + } + } + + data->driver_type = DRIVER_TYPE_QSFP; + return qsfp_probe(client, dev_id, &data->qsfp); +} + +static int sfp_msa_remove(struct i2c_client *client, struct sfp_msa_data *data) +{ + if (client->addr == SFP_EEPROM_A0_I2C_ADDR) + sfp_sysfs_eeprom_cleanup(&client->dev.kobj, &data->eeprom.bin); + if ((client->addr == SFP_CPLD_I2C_ADDR) || (client->addr == SFP_EEPROM_A0_I2C_ADDR)) + sysfs_remove_group(&client->dev.kobj, &sfp_msa_group); + kfree(data); + return 0; +} + +static int sfp_ddm_remove(struct i2c_client *client, struct sfp_ddm_data *data) +{ + if (client->addr == SFP_EEPROM_A0_I2C_ADDR) + sfp_sysfs_eeprom_cleanup(&client->dev.kobj, &data->eeprom.bin); + if ((client->addr == SFP_CPLD_I2C_ADDR) || (client->addr == SFP_EEPROM_A0_I2C_ADDR)) + sysfs_remove_group(&client->dev.kobj, &sfp_ddm_group); + kfree(data); + return 0; +} + +static int qfp_remove(struct i2c_client *client, struct qsfp_data *data) +{ + if (client->addr == SFP_EEPROM_A0_I2C_ADDR) + sfp_sysfs_eeprom_cleanup(&client->dev.kobj, &data->eeprom.bin); + if ((client->addr == SFP_CPLD_I2C_ADDR) || (client->addr == SFP_EEPROM_A0_I2C_ADDR)) + sysfs_remove_group(&client->dev.kobj, &qsfp_group); + kfree(data); + return 0; +} + +static int sfp_device_remove(struct i2c_client *client) +{ + struct sfp_port_data *data = i2c_get_clientdata(client); + + switch (data->driver_type) { + case DRIVER_TYPE_SFP_MSA: + return sfp_msa_remove(client, data->msa); + case DRIVER_TYPE_SFP_DDM: + return sfp_ddm_remove(client, data->ddm); + case DRIVER_TYPE_QSFP: + return qfp_remove(client, data->qsfp); + } + + return 0; +} + +static struct i2c_driver sfp_driver = { + .driver = { + .name = DRIVER_NAME, + }, + .probe = sfp_device_probe, + .remove = sfp_device_remove, + .id_table = sfp_device_id, + .address_list = normal_i2c, +}; + +static int __init sfp_init(void) +{ + return i2c_add_driver(&sfp_driver); +} + +static void __exit sfp_exit(void) +{ + i2c_del_driver(&sfp_driver); +} + +MODULE_AUTHOR("Philip Wang "); +MODULE_DESCRIPTION("alphanetworks snj60b0-320f driver"); +MODULE_LICENSE("GPL"); + +module_init(sfp_init); +module_exit(sfp_exit); + diff --git a/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/modules/yesm1300am.c b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/modules/yesm1300am.c new file mode 100755 index 0000000000..e0e58fd3a1 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/modules/yesm1300am.c @@ -0,0 +1,390 @@ +/* + * An hwmon driver for the 3Y Power YM-2651Y Power Module + * + * Copyright (C) 2014 Accton Technology Corporation. + * Brandon Chuang + * + * Copyright 2006 Stefan Roese , DENX Software Engineering + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Addresses scanned + */ +static const unsigned short normal_i2c[] = {0x58, 0x59, I2C_CLIENT_END}; + +/* Each client has this additional data + */ +struct yesm1300am_data +{ + struct device *hwmon_dev; + struct mutex update_lock; + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u16 v_out; /* Register value */ + u16 i_out; /* Register value */ + u8 vout_mode; /* Register value */ + u16 fan_speed; /* Register value */ + u8 mfr_id[10]; /* Register value */ + u8 mfr_model[12]; /* Register value */ +}; + +static ssize_t show_vout_by_mode(struct device *dev, struct device_attribute *da, + char *buf); +static ssize_t show_linear(struct device *dev, struct device_attribute *da, + char *buf); +static ssize_t show_ascii(struct device *dev, struct device_attribute *da, + char *buf); +static struct yesm1300am_data *yesm1300am_update_device(struct device *dev); + +enum yesm1300am_sysfs_attributes +{ + PSU_V_OUT = 0, + PSU_I_OUT, + PSU_FAN1_SPEED, + PSU_MFR_ID, + PSU_MODEL_NAME +}; + +/* sysfs attributes for hwmon + */ +static SENSOR_DEVICE_ATTR(psu_v_out, S_IRUGO, show_vout_by_mode, NULL, PSU_V_OUT); +static SENSOR_DEVICE_ATTR(psu_i_out, S_IRUGO, show_linear, NULL, PSU_I_OUT); +static SENSOR_DEVICE_ATTR(psu_fan1_speed_rpm, S_IRUGO, show_linear, NULL, PSU_FAN1_SPEED); +static SENSOR_DEVICE_ATTR(psu_mfr_id, S_IRUGO, show_ascii, NULL, PSU_MFR_ID); +static SENSOR_DEVICE_ATTR(psu_model_name, S_IRUGO, show_ascii, NULL, PSU_MODEL_NAME); + +/*Duplicate nodes for lm-sensors.*/ +static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, show_vout_by_mode, NULL, PSU_V_OUT); +static SENSOR_DEVICE_ATTR(curr2_input, S_IRUGO, show_linear, NULL, PSU_I_OUT); +static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_linear, NULL, PSU_FAN1_SPEED); + +static struct attribute *yesm1300am_attributes[] = { + &sensor_dev_attr_psu_v_out.dev_attr.attr, + &sensor_dev_attr_psu_i_out.dev_attr.attr, + &sensor_dev_attr_psu_fan1_speed_rpm.dev_attr.attr, + &sensor_dev_attr_psu_mfr_id.dev_attr.attr, + &sensor_dev_attr_psu_model_name.dev_attr.attr, + /*Duplicate nodes for lm-sensors.*/ + &sensor_dev_attr_curr2_input.dev_attr.attr, + &sensor_dev_attr_in3_input.dev_attr.attr, + &sensor_dev_attr_fan1_input.dev_attr.attr, + NULL}; + +static int two_complement_to_int(u16 data, u8 valid_bit, int mask) +{ + u16 valid_data = data & mask; + bool is_negative = valid_data >> (valid_bit - 1); + + return is_negative ? (-(((~valid_data) & mask) + 1)) : valid_data; +} + +static ssize_t show_linear(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct yesm1300am_data *data = yesm1300am_update_device(dev); + + u16 value = 0; + int exponent, mantissa; + int multiplier = 1000; + + switch (attr->index) + { + case PSU_I_OUT: + value = data->i_out; + break; + case PSU_FAN1_SPEED: + value = data->fan_speed; + multiplier = 1; + break; + } + + exponent = two_complement_to_int(value >> 11, 5, 0x1f); + mantissa = two_complement_to_int(value & 0x7ff, 11, 0x7ff); + return (exponent >= 0) ? sprintf(buf, "%d\n", (mantissa << exponent) * multiplier) : sprintf(buf, "%d\n", (mantissa * multiplier) / (1 << -exponent)); +} + +static ssize_t show_ascii(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct yesm1300am_data *data = yesm1300am_update_device(dev); + u8 *ptr = NULL; + + switch (attr->index) + { + case PSU_MFR_ID: /* psu_mfr_id */ + ptr = data->mfr_id; + break; + case PSU_MODEL_NAME: /* psu_mfr_model */ + ptr = data->mfr_model; + break; + default: + return 0; + } + + return sprintf(buf, "%s\n", ptr); +} + +static ssize_t show_vout_by_mode(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct yesm1300am_data *data = yesm1300am_update_device(dev); + int exponent, mantissa; + int multiplier = 1000; + + if (!data->valid) + { + return 0; + } + + exponent = two_complement_to_int(data->vout_mode, 5, 0x1f); + switch (attr->index) + { + case PSU_V_OUT: + mantissa = data->v_out; + break; + default: + return 0; + } + + return (exponent > 0) ? sprintf(buf, "%d\n", (mantissa << exponent) * multiplier) : sprintf(buf, "%d\n", (mantissa * multiplier) / (1 << -exponent)); +} + +static const struct attribute_group yesm1300am_group = { + .attrs = yesm1300am_attributes, +}; + +static int yesm1300am_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + struct yesm1300am_data *data; + int status; + + if (!i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_BYTE_DATA | + I2C_FUNC_SMBUS_WORD_DATA | + I2C_FUNC_SMBUS_I2C_BLOCK)) + { + status = -EIO; + goto exit; + } + + data = kzalloc(sizeof(struct yesm1300am_data), GFP_KERNEL); + if (!data) + { + status = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); + dev_info(&client->dev, "chip found\n"); + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &yesm1300am_group); + if (status) + { + goto exit_free; + } + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) + { + status = PTR_ERR(data->hwmon_dev); + goto exit_remove; + } + + dev_info(&client->dev, "%s: psu '%s'\n", + dev_name(data->hwmon_dev), client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &yesm1300am_group); +exit_free: + kfree(data); +exit: + + return status; +} + +static int yesm1300am_remove(struct i2c_client *client) +{ + struct yesm1300am_data *data = i2c_get_clientdata(client); + + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &yesm1300am_group); + kfree(data); + + return 0; +} + +static const struct i2c_device_id yesm1300am_id[] = { + {"yesm1300am", 0}, + {} +}; +MODULE_DEVICE_TABLE(i2c, yesm1300am_id); + +static struct i2c_driver yesm1300am_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "yesm1300am", + }, + .probe = yesm1300am_probe, + .remove = yesm1300am_remove, + .id_table = yesm1300am_id, + .address_list = normal_i2c, +}; + +static int yesm1300am_read_byte(struct i2c_client *client, u8 reg) +{ + return i2c_smbus_read_byte_data(client, reg); +} + +static int yesm1300am_read_word(struct i2c_client *client, u8 reg) +{ + return i2c_smbus_read_word_data(client, reg); +} + +static int yesm1300am_read_block(struct i2c_client *client, u8 command, u8 *data, + int data_len) +{ + int result = i2c_smbus_read_i2c_block_data(client, command, data_len, data); + + if (unlikely(result < 0)) + goto abort; + if (unlikely(result != data_len)) + { + result = -EIO; + goto abort; + } + + result = 0; + +abort: + return result; +} + +struct reg_data_byte +{ + u8 reg; + u8 *value; +}; + +struct reg_data_word +{ + u8 reg; + u16 *value; +}; + +static struct yesm1300am_data *yesm1300am_update_device(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct yesm1300am_data *data = i2c_get_clientdata(client); + + mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + HZ + HZ / 2) || !data->valid) + { + int i, status; + u8 command; + struct reg_data_byte regs_byte[] = {{0x20, &data->vout_mode}}; + struct reg_data_word regs_word[] = {{0x8b, &data->v_out}, + {0x8c, &data->i_out}, + {0x90, &data->fan_speed},}; + + dev_dbg(&client->dev, "Starting yesm1300am update\n"); + + /* Read byte data */ + for (i = 0; i < ARRAY_SIZE(regs_byte); i++) + { + status = yesm1300am_read_byte(client, regs_byte[i].reg); + + if (status < 0) + { + dev_dbg(&client->dev, "reg %d, err %d\n", + regs_byte[i].reg, status); + *(regs_byte[i].value) = 0; + } + else + { + *(regs_byte[i].value) = status; + } + } + + /* Read word data */ + for (i = 0; i < ARRAY_SIZE(regs_word); i++) + { + status = yesm1300am_read_word(client, regs_word[i].reg); + + if (status < 0) + { + dev_dbg(&client->dev, "reg %d, err %d\n", + regs_word[i].reg, status); + *(regs_word[i].value) = 0; + } + else + { + *(regs_word[i].value) = status; + } + } + + /* Read mfr_id */ + command = 0x99; + status = yesm1300am_read_block(client, command, data->mfr_id, + ARRAY_SIZE(data->mfr_id) - 1); + data->mfr_id[ARRAY_SIZE(data->mfr_id) - 1] = '\0'; + strncpy(data->mfr_id, (u8 *)&data->mfr_id + 1, ARRAY_SIZE(data->mfr_id) - 1); + + if (status < 0) + dev_dbg(&client->dev, "reg %d, err %d\n", command, status); + + /* Read mfr_model */ + command = 0x9a; + status = yesm1300am_read_block(client, command, data->mfr_model, + ARRAY_SIZE(data->mfr_model) - 1); + data->mfr_model[ARRAY_SIZE(data->mfr_model) - 1] = '\0'; + strncpy(data->mfr_model, (u8 *)&data->mfr_model + 1, ARRAY_SIZE(data->mfr_model) - 1); + + if (status < 0) + dev_dbg(&client->dev, "reg %d, err %d\n", command, status); + + data->last_updated = jiffies; + data->valid = 1; + } + + mutex_unlock(&data->update_lock); + + return data; +} + +module_i2c_driver(yesm1300am_driver); + +MODULE_AUTHOR("Alpha-SID6"); +MODULE_DESCRIPTION("3Y Power yesm1300am driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/service/snj60b0-platform-init.service b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/service/snj60b0-platform-init.service new file mode 100755 index 0000000000..1bb09836ed --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/service/snj60b0-platform-init.service @@ -0,0 +1,13 @@ +[Unit] +Description=Alphanetworks SNJ60B0-320F Platform initialization service +Before=pmon.service +DefaultDependencies=no + +[Service] +Type=oneshot +ExecStart=/usr/local/bin/alphanetworks_snj60b0_util.py -f install +ExecStop=/usr/local/bin/alphanetworks_snj60b0_util.py clean +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target diff --git a/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/setup.py b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/setup.py new file mode 100755 index 0000000000..26d28fc6fe --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/setup.py @@ -0,0 +1,14 @@ +#!/usr/bin/env python + +import os +from setuptools import setup +os.listdir + +setup( + name='sonic-platform', + version='1.0', + description='Module to initialize Alphanetworks SNJ60B0-320F platforms', + + packages=['sonic_platform'], +) + diff --git a/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/__init__.py b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/__init__.py new file mode 100755 index 0000000000..6241d382d9 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/__init__.py @@ -0,0 +1 @@ +__all__ = ["platform", "chassis"] \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/chassis.py new file mode 100755 index 0000000000..ef013ed869 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/chassis.py @@ -0,0 +1,219 @@ +#!/usr/bin/env python + +############################################################################# +# +# Module contains an implementation of SONiC Platform Base API and +# provides the Chassis information which are available in the platform +# +############################################################################# + +import sys +import json + +try: + from sonic_platform_base.chassis_base import ChassisBase + from .fan import Alpha_Fan as Fan + from .psu import Alpha_Psu as Psu + from .sfp import Alpha_Sfp as Sfp + from .thermal import Alpha_Thermal as Thermal + from .component import Alpha_Component as Component + from .fan_drawer import Alpha_FanDrawer as FanDrawer + from .led import Alpha_FanLed as FanLed + from .led import Alpha_PsuLed as PsuLed +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +#from xcvrd +SFP_STATUS_INSERTED = '1' +SFP_STATUS_REMOVED = '0' + +NUM_THERMAL = 3 +NUM_FANDRAWER = 6 +NUM_FANSPERDRAWER = 2 +NUM_FAN = NUM_FANDRAWER * NUM_FANSPERDRAWER +NUM_PSU = 2 +NUM_SFP = 34 +NUM_COMPONENT = 3 +CONFIG_DB_PATH = "/etc/sonic/config_db.json" + +class Chassis(ChassisBase): + """Platform-specific Chassis class""" + + # List of SfpBase-derived objects representing all sfps + # available on the chassis + _sfp_list = None + + # Leds + PSULED = None + FANLED = None + + def __init__(self): + self._sfp_list = [] + + ChassisBase.__init__(self) + # initialize thermals + for index in range(0, NUM_THERMAL): + thermal = Thermal(index) + self._thermal_list.append(thermal) + + # initialize fans, fanled + Chassis.FANLED = FanLed() + for index in range(0, NUM_FANDRAWER): + fan_drawer = FanDrawer(index) + for i in range(0, NUM_FANSPERDRAWER): + fan_index = NUM_FANSPERDRAWER * index + i + fan = Fan(fan_index) + Chassis.FANLED.add_fan(fan) + fan_drawer._fan_list.append(fan) + self._fan_list.append(fan) + self._fan_drawer_list.append(fan_drawer) + Chassis.FANLED.update_status() + + # initialize psus, psuled + Chassis.PSULED = PsuLed() + for index in range(0, NUM_PSU): + psu = Psu(index) + self._psu_list.append(psu) + Chassis.PSULED.add_psu(psu) + Chassis.PSULED.update_status() + + # initialize sfps + for index in range(0, NUM_SFP): + if (index < 32): + sfp = Sfp(index, 'QSFP') + else: + sfp = Sfp(index, 'SFP') + self._sfp_list.append(sfp) + + # initialize component + for index in range(0, NUM_COMPONENT): + component = Component(index) + self._component_list.append(component) + + def __read_config_db(self): + try: + with open(CONFIG_DB_PATH, 'r') as fd: + data = json.load(fd) + return data + except IOError: + raise IOError("Unable to open config_db file !") + + def get_base_mac(self): + """ + Retrieves the base MAC address for the chassis + Returns: + A string containing the MAC address in the format + 'XX:XX:XX:XX:XX:XX' + """ + try: + self.config_data = self.__read_config_db() + base_mac = self.config_data["DEVICE_METADATA"]["localhost"]["mac"] + return str(base_mac) + except KeyError: + raise KeyError("Base MAC not found") + + ############################################## + # SFP methods + ############################################## + + def get_num_sfps(self): + """ + Retrieves the number of sfps available on this chassis + + Returns: + An integer, the number of sfps available on this chassis + """ + return len(self._sfp_list) + + def get_all_sfps(self): + """ + Retrieves all sfps available on this chassis + + Returns: + A list of objects derived from SfpBase representing all sfps + available on this chassis + """ + return self._sfp_list + + def get_sfp(self, index): + """ + Retrieves sfp represented by (0-based) index + + Args: + index: An integer, the index (0-based) of the sfp to retrieve. + The index should be the sequence of a physical port in a chassis, + starting from 0. + For example, 0 for Ethernet0, 1 for Ethernet4 and so on. + + Returns: + An object dervied from SfpBase representing the specified sfp + """ + sfp = None + + try: + sfp = self._sfp_list[index] + except IndexError: + sys.stderr.write("SFP index {} out of range (0-{})\n".format( + index, len(self._sfp_list)-1)) + + return sfp + + def get_change_event(self, timeout=0): + """ + Returns a nested dictionary containing all devices which have + experienced a change at chassis level + + Args: + timeout: Timeout in milliseconds (optional). If timeout == 0, + this method will block until a change is detected. + + Returns: + (bool, dict): + - True if call successful, False if not; + - A nested dictionary where key is a device type, + value is a dictionary with key:value pairs in the format of + {'device_id':'device_event'}, + where device_id is the device ID for this device and + device_event, + status='1' represents device inserted, + status='0' represents device removed. + Ex. {'fan':{'0':'0', '2':'1'}, 'sfp':{'11':'0'}} + indicates that fan 0 has been removed, fan 2 + has been inserted and sfp 11 has been removed. + """ + port_dict = {} + port = Sfp._port_start + + # Check for OIR events and return updated port_dict + reg_value = Sfp.get_presence_all() + if reg_value != Sfp.sfp_status: + changed_ports = Sfp.sfp_status ^ reg_value + while (port >= Sfp._port_start) and (port <= Sfp._port_end): + + # Mask off the bit corresponding to our port + mask = (1 << port) + + if changed_ports & mask: + # port presence is high + if (reg_value & mask) == mask: + port_dict[port] = SFP_STATUS_INSERTED + else: + port_dict[port] = SFP_STATUS_REMOVED + + port += 1 + + # Update reg value + self.sfp_status = reg_value + return True, port_dict + + def get_thermal_manager(self): + from .thermal_manager import ThermalManager + return ThermalManager + + @classmethod + def get_psuled(cls): + return cls.PSULED + + @classmethod + def get_fanled(cls): + return cls.FANLED \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/component.py b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/component.py new file mode 100755 index 0000000000..1b1d4ed72d --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/component.py @@ -0,0 +1,79 @@ +#!/usr/bin/env python + +############################################################################# +# +# Module contains an implementation of SONiC Platform Base API and +# provides the component information (such as CPLD, FPGA, BIOS etc) which are available in the platform +# +############################################################################# + +try: + from sonic_platform_base.component_base import ComponentBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +COMPONENT_NAME_LIST = ["CPLD1", "CPLD2", "CPLD3"] +COMPONENT_DES_LIST = ["Main board cpld 1 (0x60)", "Main board cpld 2 (0x62)", "Main board cpld 3 (0x64)"] + +class Alpha_Component(ComponentBase): + """Platform-specific Component class""" + + + def __init__(self, component_index): + self.index = component_index+1 + self.name = self.get_name() + self.cpld_path = "/sys/bus/i2c/devices/" + self.cpld_version = "/version" + self.cpld_mapping = { + 1: "18-0060", + 2: "12-0062", + 3: "19-0064", + } + + + def get_name(self): + """ + Retrieves the name of the component + Returns: + A string containing the name of the component + """ + return COMPONENT_NAME_LIST[self.index-1] + + def get_description(self): + """ + Retrieves the description of the component + Returns: + A string containing the description of the component + """ + return COMPONENT_DES_LIST[self.index-1] + + def get_firmware_version(self): + """ + Retrieves the firmware version of module + Returns: + string: The firmware versions of the module + """ + cpld_version = None + + if "CPLD" in self.name: + node = self.cpld_path + self.cpld_mapping[self.index] + self.cpld_version + try: + with open(node, 'r') as version: + cpld_version = version.read() + except IOError: + return None + + + cpld_version = cpld_version.rstrip() + + return cpld_version + + def install_firmware(self, image_path): + """ + Install firmware to module + Args: + image_path: A string, path to firmware image + Returns: + A boolean, True if install successfully, False if not + """ + raise NotImplementedError diff --git a/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/fan.py b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/fan.py new file mode 100755 index 0000000000..1c32580b00 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/fan.py @@ -0,0 +1,224 @@ +#!/usr/bin/env python + +############################################################################# +# +# Module contains an implementation of SONiC Platform Base API and +# provides the fan status which are available in the platform +# +############################################################################# + +try: + from sonic_platform_base.fan_base import FanBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +class Alpha_Fan(FanBase): + """Platform-specific Fan class""" + + FAN_MOD_NAME = 'snj60b0_320f_fpga' + FAN_FRONT_RPM_MAX = 21000 + FAN_REAR_RPM_MAX = 19000 + FAN_SPEED_TOLERANCE_PERCENTAGE = 10 + NUM_FANTRAYS = 6 + FANS_PERTRAY = 2 + BASE_VAL_PATH = '/sys/bus/i2c/devices/0-005e/{0}' + FAN_DUTY_PATH = '/sys/bus/i2c/devices/0-005e/fan_pwm' + + def __init__(self, fan_index): + self.index = fan_index + 1 + FanBase.__init__(self) + + self.fantray_index = (fan_index)/self.FANS_PERTRAY + 1 + self.fan_index_intray = self.index - ((self.fantray_index-1)*self.FANS_PERTRAY) + + def get_name(self): + """ + Retrieves the name of the device + + Returns: + string: The name of the device + """ + return "FAN {}".format(self.index) + + def get_status(self): + """ + Retrieves the operational status of the device + + Returns: + A boolean value, True if device is operating properly, False if not + """ + status = 0 + attr = 'fan' + str(self.fantray_index) + '_fault' + node = self.BASE_VAL_PATH.format(attr) + try: + with open(node, 'r') as fault: + status = int(fault.read()) + except IOError as e: + print "Error: %s"%str(e) + return False + return False if (status > 0) else True + + def get_presence(self): + """ + Retrieves the presence of the device + + Returns: + bool: True if device is present, False if not + """ + status = 0 + attr = 'fan' + str(self.fantray_index) + '_present' + node = self.BASE_VAL_PATH.format(attr) + try: + with open(node, 'r') as presence_status: + status = int(presence_status.read()) + except IOError as e: + print "Error: %s"%str(e) + return None + return status == 1 + + def get_direction(self): + """ + Retrieves the direction of fan + + Returns: + A string, either FAN_DIRECTION_INTAKE or FAN_DIRECTION_EXHAUST + depending on fan direction + """ + direction = "" + attr = 'fan' + str(self.fantray_index) + '_direction' + node = self.BASE_VAL_PATH.format(attr) + try: + with open(node, 'r') as fan_dir: + direction = int(fan_dir.read()) + except IOError as e: + print "Error: %s"%str(e) + return self.FAN_DIRECTION_INTAKE + if direction == 1: + return self.FAN_DIRECTION_INTAKE + + return self.FAN_DIRECTION_EXHAUST + + def get_speed(self): + """ + Retrieves the speed of fan as a percentage of full speed + + Returns: + An integer, the percentage of full fan speed, in the range 0 (off) + to 100 (full speed) + """ + frpm = 0 + attr = 'fan' + str(self.fantray_index) + '_{}_speed_rpm'.format('front' if (self.fan_index_intray==1) else 'rear') + node = self.BASE_VAL_PATH.format(attr) + try: + with open(node, 'r') as speed: + frpm = int(speed.read()) + except IOError as e: + print "Error: %s"%str(e) + return 0 + + speed = 0 + if self.fan_index_intray == 1: + speed = (frpm * 100) / self.FAN_FRONT_RPM_MAX + else: + speed = (frpm * 100) / self.FAN_REAR_RPM_MAX + + if speed > 100: + speed = 100 + + return speed + + def get_speed_rpm(self): + """ + Retrieves the speed of fan in RPM + + Returns: + An integer, representing speed of the FAN in rpm + """ + frpm = 0 + attr = 'fan' + str(self.fantray_index) + '_{}_speed_rpm'.format('front' if (self.fan_index_intray==1) else 'rear') + node = self.BASE_VAL_PATH.format(attr) + try: + with open(node, 'r') as speed: + frpm = int(speed.read()) + except IOError as e: + print "Error: %s"%str(e) + return 0 + + return frpm + + def get_target_speed(self): + """ + Retrieves the target (expected) speed of the fan + + Returns: + An integer, the percentage of full fan speed, in the range 0 (off) + to 100 (full speed) + """ + duty = 0 + node = self.FAN_DUTY_PATH + try: + with open(node, 'r') as fan_duty: + duty = int(fan_duty.read()) + duty = duty * 100 / 255 + except IOError: + duty = 0 + return duty + + def set_speed(self, speed): + """ + Sets the fan speed + + Args: + speed: An integer, the percentage of full fan speed to set fan to, + in the range 0 (off) to 100 (full speed) + + Returns: + A boolean, True if speed is set successfully, False if not + """ + if speed < 0 or speed > 100: + return False + + node = self.FAN_DUTY_PATH + speed = int(round(speed * 255.0 / 100)) + try: + with open(node, 'w') as fan_duty: + fan_duty.write(str(speed)) + except IOError: + return False + return True + + def get_speed_tolerance(self): + """ + Retrieves the speed tolerance of the fan + + Returns: + An integer, the percentage of variance from target speed which is + considered tolerable + """ + return self.FAN_SPEED_TOLERANCE_PERCENTAGE + + def set_status_led(self, color): + """ + Sets the state of the fan module status LED + + Args: + color: A string representing the color with which to set the + fan module status LED + + Returns: + bool: True if status LED state is set successfully, False if not + """ + from .chassis import Chassis + fanled = Chassis.get_fanled() + return fanled.update_status() + + def get_status_led(self): + """ + Gets the state of the fan status LED + + Returns: + A string, one of the predefined STATUS_LED_COLOR_* strings above + """ + from .chassis import Chassis + fanled = Chassis.get_fanled() + return fanled.get_status() \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/fan_drawer.py b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/fan_drawer.py new file mode 100755 index 0000000000..cc22baf10b --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/fan_drawer.py @@ -0,0 +1,77 @@ +# +# fan_drawer_base.py +# +# Abstract base class for implementing a platform-specific class with which +# to interact with a fan drawer module in SONiC +# + +try: + from sonic_platform_base.fan_drawer_base import FanDrawerBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Alpha_FanDrawer(FanDrawerBase): + """ + Abstract base class for interfacing with a fan drawer + """ + # Device type definition. Note, this is a constant. + DEVICE_TYPE = "fan_drawer" + FANS_PERDRAWER = 2 + + def __init__(self, index): + FanDrawerBase.__init__(self) + self.index = index + 1 + + def get_name(self): + """ + Retrieves the name of the device + + Returns: + string: The name of the device + """ + + return "drawer{}".format(self.index) + + def get_num_fans(self): + """ + Retrieves the number of fans available on this fan drawer + + Returns: + An integer, the number of fan modules available on this fan drawer + """ + return len(self._fan_list) + + def get_all_fans(self): + """ + Retrieves all fan modules available on this fan drawer + + Returns: + A list of objects derived from FanBase representing all fan + modules available on this fan drawer + """ + return self._fan_list + + def set_status_led(self, color): + """ + Sets the state of the fan drawer status LED + + Args: + color: A string representing the color with which to set the + fan drawer status LED + + Returns: + bool: True if status LED state is set successfully, False if not + """ + # fan_drawer led not support + return True + + def get_status_led(self, color): + """ + Gets the state of the fan drawer LED + + Returns: + A string, one of the predefined STATUS_LED_COLOR_* strings above + """ + # fan_drawer led not support + return True diff --git a/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/led.py b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/led.py new file mode 100755 index 0000000000..3a5e7d1472 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/led.py @@ -0,0 +1,94 @@ +import commands + +class Led(object): + STATUS_LED_COLOR_GREEN = "green" + STATUS_LED_COLOR_AMBER = "amber" + STATUS_LED_COLOR_OFF = "off" + + value_map = { + "on": 1, + "off": 0, + "faulty": 4 + } + color_map = { + 0: STATUS_LED_COLOR_OFF, + 1: STATUS_LED_COLOR_GREEN, + 4: STATUS_LED_COLOR_AMBER + } + + _path = '' + _psu_set = set() + _fan_set = set() + + def __init__(self): + # check i2c bus order + status, output = commands.getstatusoutput("i2cdetect -l | grep I801 | grep i2c-0") + if output: + # order 0 + self._path = "/sys/bus/i2c/devices/0-005e/" + else: + # order 1 + self._path = "/sys/bus/i2c/devices/1-005e/" + + def update_status(self): + value = self.get_status_value() + + try: + with open(self.led_path, 'w') as led: + led.write(str(value)) + except IOError: + return False + + return True + + def get_status(self): + status = 0 + try: + with open(self.led_path, 'r') as led: + status = int(led.read()) + except IOError: + return False + + return self.color_map[status] + + +class Alpha_PsuLed(Led): + def __init__(self): + super(Alpha_PsuLed, self).__init__() + self.led_path = self._path + "sys_pwr" + + def add_psu(self, psu): + self._psu_set.add(psu) + + def get_status_value(self): + status = self.value_map["faulty"] + from .chassis import NUM_PSU + if len(self._psu_set) == NUM_PSU: + is_power_all_OK = True + for psu in self._psu_set: + if not psu.get_presence() or not psu.get_status(): + is_power_all_OK = False + + status = self.value_map["on"] if is_power_all_OK else self.value_map["faulty"] + return status + + +class Alpha_FanLed(Led): + def __init__(self): + super(Alpha_FanLed, self).__init__() + self.led_path = self._path + "fan1_led" + + def add_fan(self, fan): + self._fan_set.add(fan) + + def get_status_value(self): + status = self.value_map["faulty"] + from .chassis import NUM_FAN + if len(self._fan_set) == NUM_FAN: + is_fan_all_OK = True + for fan in self._fan_set: + if not fan.get_status(): + is_fan_all_OK = False + + status = self.value_map["on"] if is_fan_all_OK else self.value_map["faulty"] + return status diff --git a/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/platform.py b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/platform.py new file mode 100755 index 0000000000..58f69ba409 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/platform.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python + +############################################################################# +# +# Module contains an implementation of SONiC Platform Base API and +# provides the platform information +# +############################################################################# + +try: + from sonic_platform_base.platform_base import PlatformBase + from sonic_platform.chassis import Chassis +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Platform(PlatformBase): + """Platform-specific Platform class""" + + def __init__(self): + PlatformBase.__init__(self) + self._chassis = Chassis() diff --git a/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/psu.py b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/psu.py new file mode 100755 index 0000000000..1ab48bd8dc --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/psu.py @@ -0,0 +1,319 @@ +#!/usr/bin/env python + +############################################################################# +# +# Module contains an implementation of SONiC Platform Base API and +# provides the PSU status which are available in the platform +# +############################################################################# + +import os.path + +try: + from sonic_platform_base.psu_base import PsuBase + from sonic_platform_base.fan_base import FanBase + from sonic_eeprom import eeprom_base +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +class PsuFan(FanBase): + """Platform-specific Fan class""" + + def __init__(self, fan_index): + self.index = fan_index + 1 + self.psu_path = "/sys/bus/i2c/devices/" + self.psu_fan_rpm_max = 10000 + self.psu_fan_rpm = "/psu_fan1_speed_rpm" + if os.path.exists(self.psu_path + "9-0058"): + self.psu_pmbus_mapping = { + 1: "9-0058", + 2: "10-0059", + } + else: + self.psu_pmbus_mapping = { + 1: "32-0058", + 2: "33-0059", + } + FanBase.__init__(self) + + def get_speed(self): + """ + Retrieves the speed of fan as a percentage of full speed + + Returns: + An integer, the percentage of full fan speed, in the range 0 (off) + to 100 (full speed) + """ + rpm = 0 + node = self.psu_path + self.psu_pmbus_mapping[self.index] + self.psu_fan_rpm + try: + with open(node, 'r') as speed_rpm: + rpm = int(speed_rpm.read()) + except IOError: + return 0 + return ((rpm * 100) / self.psu_fan_rpm_max) + + def get_speed_rpm(self): + """ + Retrieves the speed of fan in revolutions per monute + + Returns: + An integer, speed of a fan in RPM + """ + rpm = 0 + node = self.psu_path + self.psu_pmbus_mapping[self.index] + self.psu_fan_rpm + try: + with open(node, 'r') as speed_rpm: + rpm = int(speed_rpm.read()) + except IOError: + return 0 + return (rpm) + + def get_direction(self): + """ + Retrieves the direction of fan + + Returns: + A string, either FAN_DIRECTION_INTAKE or FAN_DIRECTION_EXHAUST + depending on fan direction + """ + # yesm1300am not support. + + return self.FAN_DIRECTION_EXHAUST + +class Alpha_Psu(PsuBase): + """Platform-specific PSU class""" + def __init__(self, psu_index): + PsuBase.__init__(self) + fan = PsuFan(psu_index) + self._fan_list.append(fan) + self.index = psu_index + 1 + self.psu_drv = "yesm1300am" + self.psu_path = "/sys/bus/i2c/devices/" + self.psu_presence = { + 1: "/psu1_present", + 2: "/psu2_present", + } + self.psu_oper_status = { + 1: "/psu1_power_good", + 2: "/psu2_power_good", + } + self.psu_model_name = "/psu_model_name" + self.psu_serial_num = "/psu_serial_num" + self.psu_mfr_id = "/psu_mfr_id" + self.psu_v_out = "/psu_v_out" + self.psu_i_out = "/psu_i_out" + + self._PSU_EEPROM_SERIAL_NUM_OFFSET = 0x35 + self._PSU_EEPROM_SERIAL_NUM_LENGTH = 19 + + self.psu_mapping = "0-005e" + if not os.path.exists(self.psu_path + self.psu_mapping): + self.psu_mapping = "1-005e" + + if os.path.exists(self.psu_path + "9-0050"): + self.psu_eeprom_mapping = { + 1: "9-0050", + 2: "10-0051", + } + self.psu_pmbus_mapping = { + 1: "9-0058", + 2: "10-0059", + } + self.psu_serial_num = "/eeprom" + else: + self.psu_eeprom_mapping = { + 1: "32-0050", + 2: "33-0051", + } + self.psu_pmbus_mapping = { + 1: "32-0058", + 2: "33-0059", + } + + def get_name(self): + """ + Retrieves the name of the device + + Returns: + string: The name of the device + """ + return "{}-i2c-{}".format(self.psu_drv, self.psu_pmbus_mapping[self.index]) + + def get_presence(self): + """ + Retrieves the presence of the device + + Returns: + bool: True if device is present, False if not + """ + status = 0 + node = self.psu_path + self.psu_mapping + self.psu_presence[self.index] + try: + with open(node, 'r') as presence_status: + status = int(presence_status.read()) + except IOError: + return False + return status == 1 + + def get_status(self): + """ + Retrieves the operational status of the device + + Returns: + A boolean value, True if device is operating properly, False if not + """ + status = 0 + node = self.psu_path + self.psu_mapping + self.psu_oper_status[self.index] + try: + with open(node, 'r') as power_status: + status = int(power_status.read()) + except IOError: + return False + return status == 1 + + def get_model(self): + """ + Retrieves the model number (or part number) of the device + + Returns: + string: Model/part number of device + """ + model = "" + node = self.psu_path + self.psu_pmbus_mapping[self.index] + self.psu_model_name + try: + with open(node, 'r') as model_name: + model = model_name.read() + except IOError: + return None + return model.rstrip() + + def get_mfr_id(self): + """ + Retrieves the manufacturer's name (or id) of the device + + Returns: + string: Manufacturer's id of device + """ + mfr = "" + node = self.psu_path + self.psu_pmbus_mapping[self.index] + self.psu_mfr_id + try: + with open(node, 'r') as mfr_id: + mfr = mfr_id.read() + except IOError: + return None + return mfr.rstrip() + + def get_serial(self): + """ + Retrieves the serial number of the device + + Returns: + string: Serial number of device + """ + serial = "" + node = self.psu_path + self.psu_eeprom_mapping[self.index] + self.psu_serial_num + if self.psu_serial_num == "/eeprom": + try: + psu_eeprom = eeprom_base.EepromDecoder(node, None, 0, '', True) + serial = psu_eeprom.read_eeprom_bytes(self._PSU_EEPROM_SERIAL_NUM_LENGTH, self._PSU_EEPROM_SERIAL_NUM_OFFSET) + if len(serial) != self._PSU_EEPROM_SERIAL_NUM_LENGTH: + return None + except IOError: + return None + else: + try: + with open(node, 'r') as serial_num: + serial = serial_num.read() + except IOError: + return None + + return serial.rstrip() + + def get_voltage(self): + """ + Retrieves current PSU voltage output + + Returns: + A float number, the output voltage in volts, + e.g. 12.1 + """ + vout = 0 + node = self.psu_path + self.psu_pmbus_mapping[self.index] + self.psu_v_out + try: + with open(node, 'r') as v_out: + vout = int(v_out.read()) + except IOError: + return 0 + return float(vout) / 1000 + + def get_current(self): + """ + Retrieves present electric current supplied by PSU + + Returns: + A float number, the electric current in amperes, e.g 15.4 + """ + iout = 0 + node = self.psu_path + self.psu_pmbus_mapping[self.index] + self.psu_i_out + try: + with open(node, 'r') as i_out: + iout = int(i_out.read()) + except IOError: + return 0 + return float(iout) / 1000 + + def get_powergood_status(self): + """ + Retrieves the powergood status of PSU + + Returns: + A boolean, True if PSU has stablized its output voltages and passed all + its internal self-tests, False if not. + """ + status = 0 + node = self.psu_path + self.psu_mapping + self.psu_oper_status[self.index] + try: + with open(node, 'r') as powergood_status: + status = int(powergood_status.read()) + except IOError: + return False + return status == 1 + + def get_power(self): + """ + Retrieves current energy supplied by PSU + + Returns: + A float number, the power in watts, e.g. 302.6 + """ + # yesm1300am not support. + pout = 0 + + return pout + + def set_status_led(self, color): + """ + Sets the state of the PSU status LED + + Args: + color: A string representing the color with which to set the + PSU status LED + + Returns: + bool: True if status LED state is set successfully, False if not + """ + from .platform import Chassis + psuled = Chassis.get_psuled() + return psuled.update_status() + + def get_status_led(self): + """ + Gets the state of the PSU status LED + + Returns: + A string, one of the predefined STATUS_LED_COLOR_* strings above + """ + from .chassis import Chassis + psuled = Chassis.get_psuled() + return psuled.get_status() diff --git a/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/sfp.py b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/sfp.py new file mode 100755 index 0000000000..b2ed5a6fa4 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/sfp.py @@ -0,0 +1,925 @@ +#!/usr/bin/env python + +############################################################################# +# +# Module contains an implementation of SONiC Platform Base API and +# provides the SFP management routines +# +############################################################################# + +try: + import os.path + import time + from sonic_platform_base.sfp_base import SfpBase + from sonic_platform_base.sonic_sfp.sff8436 import sff8436InterfaceId + from sonic_platform_base.sonic_sfp.sff8436 import sff8436Dom + from sonic_platform_base.sonic_sfp.sff8472 import sff8472InterfaceId + from sonic_platform_base.sonic_sfp.sff8472 import sff8472Dom + from sonic_platform_base.sonic_sfp.sff8472 import sffbase + from sonic_platform_base.sonic_sfp.inf8628 import inf8628InterfaceId +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +# definitions of the offset and width for values in XCVR info eeprom +XCVR_INTFACE_BULK_OFFSET = 0 +XCVR_INTFACE_BULK_WIDTH_QSFP = 20 +XCVR_INTFACE_BULK_WIDTH_SFP = 21 +XCVR_TYPE_OFFSET = 0 +XCVR_TYPE_WIDTH = 1 +XCVR_EXT_TYPE_OFFSET = 1 +XCVR_EXT_TYPE_WIDTH = 1 +XCVR_CONNECTOR_OFFSET = 2 +XCVR_CONNECTOR_WIDTH = 1 +XCVR_COMPLIANCE_CODE_OFFSET = 3 +XCVR_COMPLIANCE_CODE_WIDTH = 8 +XCVR_ENCODING_OFFSET = 11 +XCVR_ENCODING_WIDTH = 1 +XCVR_NBR_OFFSET = 12 +XCVR_NBR_WIDTH = 1 +XCVR_EXT_RATE_SEL_OFFSET = 13 +XCVR_EXT_RATE_SEL_WIDTH = 1 +XCVR_CABLE_LENGTH_OFFSET = 14 +XCVR_CABLE_LENGTH_WIDTH_QSFP = 5 +# XCVR_CABLE_LENGTH_WIDTH_SFP = 6 +XCVR_VENDOR_NAME_OFFSET = 20 +XCVR_VENDOR_NAME_WIDTH = 16 +XCVR_VENDOR_OUI_OFFSET = 37 +XCVR_VENDOR_OUI_WIDTH = 3 +XCVR_VENDOR_PN_OFFSET = 40 +XCVR_VENDOR_PN_WIDTH = 16 +XCVR_HW_REV_OFFSET = 56 +XCVR_HW_REV_WIDTH_OSFP = 2 +XCVR_HW_REV_WIDTH_QSFP = 2 +XCVR_HW_REV_WIDTH_SFP = 4 +XCVR_VENDOR_SN_OFFSET = 68 +XCVR_VENDOR_SN_WIDTH = 16 +XCVR_VENDOR_DATE_OFFSET = 84 +XCVR_VENDOR_DATE_WIDTH = 8 +XCVR_DOM_CAPABILITY_OFFSET = 92 +XCVR_DOM_CAPABILITY_WIDTH = 1 + +# definitions of the offset for values in OSFP info eeprom +OSFP_TYPE_OFFSET = 0 +OSFP_VENDOR_NAME_OFFSET = 129 +OSFP_VENDOR_PN_OFFSET = 148 +OSFP_HW_REV_OFFSET = 164 +OSFP_VENDOR_SN_OFFSET = 166 + +#definitions of the offset and width for values in DOM info eeprom +QSFP_DOM_REV_OFFSET = 1 +QSFP_DOM_REV_WIDTH = 1 +QSFP_TEMPE_OFFSET = 22 +QSFP_TEMPE_WIDTH = 2 +QSFP_VOLT_OFFSET = 26 +QSFP_VOLT_WIDTH = 2 +QSFP_CHANNL_MON_OFFSET = 34 +QSFP_CHANNL_MON_WIDTH = 16 +QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH = 24 +QSFP_CONTROL_OFFSET = 86 +QSFP_CONTROL_WIDTH = 8 +QSFP_CHANNL_RX_LOS_STATUS_OFFSET = 3 +QSFP_CHANNL_RX_LOS_STATUS_WIDTH = 1 +QSFP_CHANNL_TX_FAULT_STATUS_OFFSET = 4 +QSFP_CHANNL_TX_FAULT_STATUS_WIDTH = 1 +QSFP_POWEROVERRIDE_OFFSET = 93 +QSFP_POWEROVERRIDE_WIDTH = 1 +QSFP_MODULE_THRESHOLD_OFFSET = 128 +QSFP_MODULE_THRESHOLD_WIDTH = 24 +QSFP_CHANNEL_THRESHOLD_OFFSET = 176 +QSFP_CHANNEL_THRESHOLD_WIDTH = 16 + + +SFP_TEMPE_OFFSET = 96 +SFP_TEMPE_WIDTH = 2 +SFP_VOLT_OFFSET = 98 +SFP_VOLT_WIDTH = 2 +SFP_CHANNL_MON_OFFSET = 100 +SFP_CHANNL_MON_WIDTH = 6 +SFP_MODULE_THRESHOLD_OFFSET = 0 +SFP_MODULE_THRESHOLD_WIDTH = 40 +SFP_CHANNL_THRESHOLD_OFFSET = 112 +SFP_CHANNL_THRESHOLD_WIDTH = 2 +SFP_STATUS_CONTROL_OFFSET = 110 +SFP_STATUS_CONTROL_WIDTH = 1 +SFP_TX_DISABLE_HARD_BIT = 7 +SFP_TX_DISABLE_SOFT_BIT = 6 + + +qsfp_cable_length_tup = ('Length(km)', 'Length OM3(2m)', + 'Length OM2(m)', 'Length OM1(m)', + 'Length Cable Assembly(m)') + +sfp_cable_length_tup = ('LengthSMFkm-UnitsOfKm', 'LengthSMF(UnitsOf100m)', + 'Length50um(UnitsOf10m)', 'Length62.5um(UnitsOfm)', + 'LengthCable(UnitsOfm)', 'LengthOM3(UnitsOf10m)') + +sfp_compliance_code_tup = ('10GEthernetComplianceCode', 'InfinibandComplianceCode', + 'ESCONComplianceCodes', 'SONETComplianceCodes', + 'EthernetComplianceCodes','FibreChannelLinkLength', + 'FibreChannelTechnology', 'SFP+CableTechnology', + 'FibreChannelTransmissionMedia','FibreChannelSpeed') + +qsfp_compliance_code_tup = ('10/40G Ethernet Compliance Code', 'SONET Compliance codes', + 'SAS/SATA compliance codes', 'Gigabit Ethernet Compliant codes', + 'Fibre Channel link length/Transmitter Technology', + 'Fibre Channel transmission media', 'Fibre Channel Speed') + +PAGE_OFFSET = 0 +KEY_OFFSET = 1 +KEY_WIDTH = 2 +FUNC_NAME = 3 + +INFO_OFFSET = 128 +DOM_OFFSET = 0 +DOM_OFFSET1 = 384 + +CPLD_PORT_NUM = 8 +SFP_PATH = "/sys/bus/i2c/devices/{0}-005f" +SFPPLUS_PATH = "/sys/bus/i2c/devices/{0}-005e" +SFPPLUS_EEPROM_PATH = "/sys/bus/i2c/devices/{0}-0050" + +class Alpha_Sfp(SfpBase): + """Platform-specific Sfp class""" + _port_start = 0 + _port_end = 34 + + sfp_status = 0 + + port_to_eeprom = {} + + port_to_i2cbus_0 = { + 1 : 13, + 2 : 14, + 3 : 15, + 4 : 16, + 5 : 12, + 6 : 11, + } + + port_to_i2cbus_1 = { + 1 : 14, + 2 : 15, + 3 : 16, + 4 : 17, + 5 : 13, + 6 : 12, + } + + port_to_i2cbus_mapping = {} + + sfpplus_eeprom_path = SFPPLUS_EEPROM_PATH+"/sfp_eeprom" + eeprom_path = SFP_PATH+"/sfp{1}_eeprom" + port_reset_path = SFP_PATH+"/sfp{1}_port_reset" + present_path = SFP_PATH+"/sfp{1}_is_present" + sfpplus_present_path = SFPPLUS_PATH+"/sfp_present" + lpmode_path = SFP_PATH+"/sfp{1}_lpmode" + + # Read out any bytes from any offset + def __read_eeprom_specific_bytes(self, offset, num_bytes): + sysfsfile_eeprom = None + eeprom_raw = [] + for i in range(0, num_bytes): + eeprom_raw.append("0x00") + + try: + sysfsfile_eeprom = open(self.port_to_eeprom[self.index], mode="rb", buffering=0) + sysfsfile_eeprom.seek(offset) + raw = sysfsfile_eeprom.read(num_bytes) + for n in range(0, num_bytes): + eeprom_raw[n] = hex(ord(raw[n]))[2:].zfill(2) + except Exception as e: + pass + finally: + if sysfsfile_eeprom: + sysfsfile_eeprom.close() + + return eeprom_raw + + def __init__(self, sfp_index, sfp_type): + SfpBase.__init__(self) + self.index = sfp_index + + # index is 0-based + if sfp_index < self._port_start or sfp_index >= self._port_end: + print "Invalid port index %d"%sfp_index + return + + self.is_qsfp_port = True if (sfp_type=='QSFP' or sfp_type=='QSFP28') else False + self.is_osfp_port = True if (sfp_type=='OSFP' or sfp_type=='QSFP-DD') else False + self.is_sfp_port = True if (sfp_type=='SFP') else False + + path = self.present_path + port_path = path.format(self.port_to_i2cbus_0[1], 1) + if not os.path.exists(port_path): + self.port_to_i2cbus_mapping = self.port_to_i2cbus_1 + else: + self.port_to_i2cbus_mapping = self.port_to_i2cbus_0 + + index = (self.index % CPLD_PORT_NUM) + 1 + cpld_index = (self.index / CPLD_PORT_NUM) + 1 + if cpld_index == 5: + path = self.sfpplus_eeprom_path + if index == 1: + self.port_to_eeprom[self.index] = path.format(self.port_to_i2cbus_mapping[cpld_index]) + else: + self.port_to_eeprom[self.index] = path.format(self.port_to_i2cbus_mapping[cpld_index+1]) + else: + path = self.eeprom_path + self.port_to_eeprom[self.index] = path.format(self.port_to_i2cbus_mapping[cpld_index], index) + + self.info_dict_keys = ['type', 'hardwarerev', 'serialnum', 'manufacturename', 'modelname', 'Connector', 'encoding', 'ext_identifier', + 'ext_rateselect_compliance', 'cable_type', 'cable_length', 'nominal_bit_rate', 'specification_compliance', 'vendor_date', 'vendor_oui'] + + self.dom_dict_keys = ['rx_los', 'tx_fault', 'reset_status', 'power_lpmode', 'tx_disable', 'tx_disable_channel', 'temperature', 'voltage', + 'rx1power', 'rx2power', 'rx3power', 'rx4power', 'tx1bias', 'tx2bias', 'tx3bias', 'tx4bias', 'tx1power', 'tx2power', 'tx3power', 'tx4power'] + + self.threshold_dict_keys = ['temphighalarm', 'temphighwarning', 'templowalarm', 'templowwarning', 'vcchighalarm', 'vcchighwarning', 'vcclowalarm', 'vcclowwarning', 'rxpowerhighalarm', 'rxpowerhighwarning', + 'rxpowerlowalarm', 'rxpowerlowwarning', 'txpowerhighalarm', 'txpowerhighwarning', 'txpowerlowalarm', 'txpowerlowwarning', 'txbiashighalarm', 'txbiashighwarning', 'txbiaslowalarm', 'txbiaslowwarning'] + + SfpBase.__init__(self) + + def get_presence(self): + """ + Retrieves the presence of the device + + Returns: + bool: True if device is present, False if not + """ + cpld_index = (self.index / CPLD_PORT_NUM) + 1 + index = (self.index % CPLD_PORT_NUM) + 1 + if cpld_index == 5: + path = self.sfpplus_present_path + port_path = path.format(0) + else: + path = self.present_path + port_path = path.format(self.port_to_i2cbus_mapping[cpld_index], index) + + try: + reg_file = open(port_path, 'r') + reg_value = int(reg_file.readline().rstrip(), 16) + reg_file.close() + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + if cpld_index == 5: + if reg_value == 3: + # SFP+ 1 and 0 is not present, 0 is present + reg_value = 0 + else: + if index == 1: + reg_value = (reg_value < 2) + else: + reg_value = ((reg_value % 2) == 0) + return reg_value + + def get_presence_all(self): + bitmap = "" + port = self._port_start + + while (port >= self._port_start) and (port <= self._port_end): + self.index = port + reg_value = self.get_presence() + + if reg_value: + bitmap += '1' + " " + else: + bitmap += '0' + " " + + port += 1 + + content = bitmap.split(" ") + content = "".join(content[::-1]) + + return int(content, 2) + + def get_transceiver_info(self): + """ + Retrieves transceiver info of this SFP + + Returns: + A dict which contains following keys/values : + ======================================================================== + keys |Value Format |Information + ---------------------------|---------------|---------------------------- + type |1*255VCHAR |type of SFP + hardwarerev |1*255VCHAR |hardware version of SFP + serialnum |1*255VCHAR |serial number of the SFP + manufacturename |1*255VCHAR |SFP vendor name + modelname |1*255VCHAR |SFP model name + Connector |1*255VCHAR |connector information + encoding |1*255VCHAR |encoding information + ext_identifier |1*255VCHAR |extend identifier + ext_rateselect_compliance |1*255VCHAR |extended rateSelect compliance + cable_length |INT |cable length in m + mominal_bit_rate |INT |nominal bit rate by 100Mbs + specification_compliance |1*255VCHAR |specification compliance + vendor_date |1*255VCHAR |vendor date + vendor_oui |1*255VCHAR |vendor OUI + ======================================================================== + """ + # check present status + if not self.get_presence(): + return None + + + if self.is_osfp_port: + sfpi_obj = inf8628InterfaceId() + offset = 0 + type_offset = OSFP_TYPE_OFFSET + vendor_rev_width = XCVR_HW_REV_WIDTH_OSFP + hw_rev_offset = OSFP_HW_REV_OFFSET + vendor_name_offset = OSFP_VENDOR_NAME_OFFSET + vendor_pn_offset = OSFP_VENDOR_PN_OFFSET + vendor_sn_offset = OSFP_VENDOR_SN_OFFSET + # cable_length_width = XCVR_CABLE_LENGTH_WIDTH_QSFP + interface_info_bulk_width = XCVR_INTFACE_BULK_WIDTH_QSFP + sfp_type = 'OSFP' + + elif self.is_qsfp_port: + sfpi_obj = sff8436InterfaceId() + offset = 128 + type_offset = XCVR_TYPE_OFFSET + vendor_rev_width = XCVR_HW_REV_WIDTH_QSFP + hw_rev_offset = XCVR_HW_REV_OFFSET + vendor_name_offset = XCVR_VENDOR_NAME_OFFSET + vendor_pn_offset = XCVR_VENDOR_PN_OFFSET + vendor_sn_offset = XCVR_VENDOR_SN_OFFSET + # cable_length_width = XCVR_CABLE_LENGTH_WIDTH_QSFP + interface_info_bulk_width = XCVR_INTFACE_BULK_WIDTH_QSFP + sfp_type = 'QSFP' + else: + sfpi_obj = sff8472InterfaceId() + offset = 0 + type_offset = XCVR_TYPE_OFFSET + vendor_rev_width = XCVR_HW_REV_WIDTH_SFP + hw_rev_offset = XCVR_HW_REV_OFFSET + vendor_name_offset = XCVR_VENDOR_NAME_OFFSET + vendor_pn_offset = XCVR_VENDOR_PN_OFFSET + vendor_sn_offset = XCVR_VENDOR_SN_OFFSET + # cable_length_width = XCVR_CABLE_LENGTH_WIDTH_SFP + interface_info_bulk_width = XCVR_INTFACE_BULK_WIDTH_SFP + sfp_type = 'SFP' + + if sfpi_obj is None: + return None + + + if self.is_osfp_port: + sfp_type_raw = self.__read_eeprom_specific_bytes((offset + type_offset), XCVR_TYPE_WIDTH) + if sfp_type_raw is not None: + sfp_type_data = sfpi_obj.parse_sfp_type(sfp_type_raw, 0) + sfp_type_abbrv_name = sfpi_obj.parse_sfp_type_abbrv_name(sfp_typ_raw, 0) + else: + sfp_interface_bulk_raw = self.__read_eeprom_specific_bytes((offset + XCVR_INTFACE_BULK_OFFSET), interface_info_bulk_width) + if sfp_interface_bulk_raw is not None: + sfp_interface_bulk_data = sfpi_obj.parse_sfp_info_bulk(sfp_interface_bulk_raw, 0) + + sfp_vendor_oui_raw = self.__read_eeprom_specific_bytes((offset + XCVR_VENDOR_OUI_OFFSET), XCVR_VENDOR_OUI_WIDTH) + if sfp_vendor_oui_raw is not None: + sfp_vendor_oui_data = sfpi_obj.parse_vendor_oui(sfp_vendor_oui_raw, 0) + + sfp_vendor_date_raw = self.__read_eeprom_specific_bytes((offset + XCVR_VENDOR_DATE_OFFSET), XCVR_VENDOR_DATE_WIDTH) + if sfp_vendor_date_raw is not None: + sfp_vendor_date_data = sfpi_obj.parse_vendor_date(sfp_vendor_date_raw, 0) + + + sfp_vendor_name_raw = self.__read_eeprom_specific_bytes( + (offset + vendor_name_offset), XCVR_VENDOR_NAME_WIDTH) + sfp_vendor_name_data = sfpi_obj.parse_vendor_name( + sfp_vendor_name_raw, 0) + + sfp_vendor_pn_raw = self.__read_eeprom_specific_bytes( + (offset + vendor_pn_offset), XCVR_VENDOR_PN_WIDTH) + sfp_vendor_pn_data = sfpi_obj.parse_vendor_pn( + sfp_vendor_pn_raw, 0) + + sfp_vendor_rev_raw = self.__read_eeprom_specific_bytes( + (offset + hw_rev_offset), vendor_rev_width) + sfp_vendor_rev_data = sfpi_obj.parse_vendor_rev( + sfp_vendor_rev_raw, 0) + + sfp_vendor_sn_raw = self.__read_eeprom_specific_bytes( + (offset + vendor_sn_offset), XCVR_VENDOR_SN_WIDTH) + sfp_vendor_sn_data = sfpi_obj.parse_vendor_sn( + sfp_vendor_sn_raw, 0) + + xcvr_info_dict = dict.fromkeys(self.info_dict_keys, 'N/A') + compliance_code_dict = dict() + + if sfp_interface_bulk_data: + xcvr_info_dict['type'] = sfp_interface_bulk_data['data']['type']['value'] + xcvr_info_dict['Connector'] = sfp_interface_bulk_data['data']['Connector']['value'] + xcvr_info_dict['encoding'] = sfp_interface_bulk_data['data']['EncodingCodes']['value'] + xcvr_info_dict['ext_identifier'] = sfp_interface_bulk_data['data']['Extended Identifier']['value'] + xcvr_info_dict['ext_rateselect_compliance'] = sfp_interface_bulk_data['data']['RateIdentifier']['value'] + xcvr_info_dict['type_abbrv_name'] = sfp_interface_bulk_data['data']['type_abbrv_name']['value'] + else: + xcvr_info_dict['type'] = sfp_type_data['data']['type']['value'] if sfp_type_data else 'N/A' + xcvr_info_dict['type_abbrv_name'] = sfp_type_abbrv_name['data']['type_abbrv_name']['value'] if sfp_type_abbrv_name else 'N/A' + + xcvr_info_dict['manufacturename'] = sfp_vendor_name_data['data']['Vendor Name']['value'] if sfp_vendor_name_data else 'N/A' + xcvr_info_dict['modelname'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] if sfp_vendor_pn_data else 'N/A' + xcvr_info_dict['hardwarerev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] if sfp_vendor_rev_data else 'N/A' + xcvr_info_dict['serialnum'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] if sfp_vendor_sn_data else 'N/A' + xcvr_info_dict['vendor_oui'] = sfp_vendor_oui_data['data']['Vendor OUI']['value'] if sfp_vendor_oui_data else 'N/A' + xcvr_info_dict['vendor_date'] = sfp_vendor_date_data['data']['VendorDataCode(YYYY-MM-DD Lot)']['value'] if sfp_vendor_date_data else 'N/A' + xcvr_info_dict['cable_type'] = "Unknown" + xcvr_info_dict['cable_length'] = "Unknown" + + if sfp_type == 'QSFP': + for key in qsfp_cable_length_tup: + if key in sfp_interface_bulk_data['data']: + xcvr_info_dict['cable_type'] = key + xcvr_info_dict['cable_length'] = str(sfp_interface_bulk_data['data'][key]['value']) + + for key in qsfp_compliance_code_tup: + if key in sfp_interface_bulk_data['data']['Specification compliance']['value']: + compliance_code_dict[key] = sfp_interface_bulk_data['data']['Specification compliance']['value'][key]['value'] + xcvr_info_dict['specification_compliance'] = str(compliance_code_dict) + + nkey='Nominal Bit Rate(100Mbs)' + if nkey in sfp_interface_bulk_data['data']: + xcvr_info_dict['nominal_bit_rate'] = str(sfp_interface_bulk_data['data']['Nominal Bit Rate(100Mbs)']['value']) + else: + xcvr_info_dict['nominal_bit_rate'] = 'N/A' + else: + for key in sfp_cable_length_tup: + if key in sfp_interface_bulk_data['data']: + xcvr_info_dict['cable_type'] = key + xcvr_info_dict['cable_length'] = str(sfp_interface_bulk_data['data'][key]['value']) + + for key in sfp_compliance_code_tup: + if key in sfp_interface_bulk_data['data']['Specification compliance']['value']: + compliance_code_dict[key] = sfp_interface_bulk_data['data']['Specification compliance']['value'][key]['value'] + xcvr_info_dict['specification_compliance'] = str(compliance_code_dict) + + xcvr_info_dict['nominal_bit_rate'] = str(sfp_interface_bulk_data['data']['NominalSignallingRate(UnitsOf100Mbd)']['value']) + + return xcvr_info_dict + + def get_transceiver_bulk_status(self): + """ + Retrieves transceiver bulk status of this SFP + + Returns: + A dict which contains following keys/values : + ======================================================================== + keys |Value Format |Information + ---------------------------|---------------|---------------------------- + RX LOS |BOOLEAN |RX lost-of-signal status, + | |True if has RX los, False if not. + TX FAULT |BOOLEAN |TX fault status, + | |True if has TX fault, False if not. + Reset status |BOOLEAN |reset status, + | |True if SFP in reset, False if not. + LP mode |BOOLEAN |low power mode status, + | |True in lp mode, False if not. + TX disable |BOOLEAN |TX disable status, + | |True TX disabled, False if not. + TX disabled channel |HEX |disabled TX channles in hex, + | |bits 0 to 3 represent channel 0 + | |to channel 3. + Temperature |INT |module temperature in Celsius + Voltage |INT |supply voltage in mV + TX bias |INT |TX Bias Current in mA + RX power |INT |received optical power in mW + TX power |INT |TX output power in mW + ======================================================================== + """ + # check present status + if not self.get_presence(): + return None + + xcvr_dom_info_dict = dict.fromkeys(self.dom_dict_keys, 'N/A') + + if self.is_osfp_port: + # Below part is added to avoid fail xcvrd, shall be implemented later + pass + elif self.is_qsfp_port: + # QSFPs + offset = 0 + offset_xcvr = 128 + + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return None + + sfpi_obj = sff8436InterfaceId() + if sfpi_obj is None: + return None + + qsfp_dom_capability_raw = self.__read_eeprom_specific_bytes( + (offset_xcvr + XCVR_DOM_CAPABILITY_OFFSET), XCVR_DOM_CAPABILITY_WIDTH) + if qsfp_dom_capability_raw is not None: + qspf_dom_capability_data = sfpi_obj.parse_qsfp_dom_capability( + qsfp_dom_capability_raw, 0) + else: + return None + + dom_temperature_raw = self.__read_eeprom_specific_bytes( (offset + QSFP_TEMPE_OFFSET), QSFP_TEMPE_WIDTH) + if dom_temperature_raw is not None: + dom_temperature_data = sfpd_obj.parse_temperature(dom_temperature_raw, 0) + else: + return None + + dom_voltage_raw = self.__read_eeprom_specific_bytes( (offset + QSFP_VOLT_OFFSET), QSFP_VOLT_WIDTH) + if dom_voltage_raw is not None: + dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0) + else: + return None + + qsfp_dom_rev_raw = self.__read_eeprom_specific_bytes( (offset + QSFP_DOM_REV_OFFSET), QSFP_DOM_REV_WIDTH) + if qsfp_dom_rev_raw is not None: + qsfp_dom_rev_data = sfpd_obj.parse_sfp_dom_rev(qsfp_dom_rev_raw, 0) + else: + return None + + xcvr_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value'] + xcvr_dom_info_dict['voltage'] = dom_voltage_data['data']['Vcc']['value'] + + # The tx_power monitoring is only available on QSFP which compliant with SFF-8636 + # and claimed that it support tx_power with one indicator bit. + dom_channel_monitor_data = {} + qsfp_dom_rev = qsfp_dom_rev_data['data']['dom_rev']['value'] + qsfp_tx_power_support = qspf_dom_capability_data['data']['Tx_power_support']['value'] + if (qsfp_dom_rev[0:8] != 'SFF-8636' or (qsfp_dom_rev[0:8] == 'SFF-8636' and qsfp_tx_power_support != 'on')): + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes((offset + QSFP_CHANNL_MON_OFFSET), QSFP_CHANNL_MON_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params(dom_channel_monitor_raw, 0) + else: + return None + + xcvr_dom_info_dict['tx1power'] = 'N/A' + xcvr_dom_info_dict['tx2power'] = 'N/A' + xcvr_dom_info_dict['tx3power'] = 'N/A' + xcvr_dom_info_dict['tx4power'] = 'N/A' + else: + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes((offset + QSFP_CHANNL_MON_OFFSET), QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params_with_tx_power(dom_channel_monitor_raw, 0) + else: + return None + + + xcvr_dom_info_dict['tx1power'] = dom_channel_monitor_data['data']['TX1Power']['value'] + xcvr_dom_info_dict['tx2power'] = dom_channel_monitor_data['data']['TX2Power']['value'] + xcvr_dom_info_dict['tx3power'] = dom_channel_monitor_data['data']['TX3Power']['value'] + xcvr_dom_info_dict['tx4power'] = dom_channel_monitor_data['data']['TX4Power']['value'] + + if dom_channel_monitor_raw: + xcvr_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value'] + xcvr_dom_info_dict['voltage'] = dom_voltage_data['data']['Vcc']['value'] + xcvr_dom_info_dict['rx1power'] = dom_channel_monitor_data['data']['RX1Power']['value'] + xcvr_dom_info_dict['rx2power'] = dom_channel_monitor_data['data']['RX2Power']['value'] + xcvr_dom_info_dict['rx3power'] = dom_channel_monitor_data['data']['RX3Power']['value'] + xcvr_dom_info_dict['rx4power'] = dom_channel_monitor_data['data']['RX4Power']['value'] + xcvr_dom_info_dict['tx1bias'] = dom_channel_monitor_data['data']['TX1Bias']['value'] + xcvr_dom_info_dict['tx2bias'] = dom_channel_monitor_data['data']['TX2Bias']['value'] + xcvr_dom_info_dict['tx3bias'] = dom_channel_monitor_data['data']['TX3Bias']['value'] + xcvr_dom_info_dict['tx4bias'] = dom_channel_monitor_data['data']['TX4Bias']['value'] + + else: + # SFPs + offset = 256 + + sfpd_obj = sff8472Dom() + if sfpd_obj is None: + return None + + dom_temperature_raw = self.__read_eeprom_specific_bytes( (offset + SFP_TEMPE_OFFSET), SFP_TEMPE_WIDTH) + if dom_temperature_raw is not None: + dom_temperature_data = sfpd_obj.parse_temperature(dom_temperature_raw, 0) + else: + return None + + dom_voltage_raw = self.__read_eeprom_specific_bytes( (offset + SFP_VOLT_OFFSET), SFP_VOLT_WIDTH) + if dom_voltage_raw is not None: + dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0) + else: + return None + + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( (offset + SFP_CHANNL_MON_OFFSET), SFP_CHANNL_MON_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params(dom_channel_monitor_raw, 0) + else: + return None + + xcvr_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value'] + xcvr_dom_info_dict['voltage'] = dom_voltage_data['data']['Vcc']['value'] + xcvr_dom_info_dict['rx1power'] = dom_channel_monitor_data['data']['RXPower']['value'] + xcvr_dom_info_dict['rx2power'] = 'N/A' + xcvr_dom_info_dict['rx3power'] = 'N/A' + xcvr_dom_info_dict['rx4power'] = 'N/A' + xcvr_dom_info_dict['tx1bias'] = dom_channel_monitor_data['data']['TXBias']['value'] + xcvr_dom_info_dict['tx2bias'] = 'N/A' + xcvr_dom_info_dict['tx3bias'] = 'N/A' + xcvr_dom_info_dict['tx4bias'] = 'N/A' + xcvr_dom_info_dict['tx1power'] = dom_channel_monitor_data['data']['TXPower']['value'] + xcvr_dom_info_dict['tx2power'] = 'N/A' + xcvr_dom_info_dict['tx3power'] = 'N/A' + xcvr_dom_info_dict['tx4power'] = 'N/A' + + xcvr_dom_info_dict['rx_los'] = self.get_rx_los() + xcvr_dom_info_dict['tx_fault'] = self.get_tx_fault() + xcvr_dom_info_dict['reset_status'] = self.get_reset_status() + xcvr_dom_info_dict['lp_mode'] = self.get_lpmode() + + + return xcvr_dom_info_dict + + def get_transceiver_threshold_info(self): + """ + Retrieves transceiver threshold info of this SFP + Returns: + A dict which contains following keys/values : + ======================================================================== + keys |Value Format |Information + ---------------------------|---------------|---------------------------- + temphighalarm |FLOAT |High Alarm Threshold value of temperature in Celsius. + templowalarm |FLOAT |Low Alarm Threshold value of temperature in Celsius. + temphighwarning |FLOAT |High Warning Threshold value of temperature in Celsius. + templowwarning |FLOAT |Low Warning Threshold value of temperature in Celsius. + vcchighalarm |FLOAT |High Alarm Threshold value of supply voltage in mV. + vcclowalarm |FLOAT |Low Alarm Threshold value of supply voltage in mV. + vcchighwarning |FLOAT |High Warning Threshold value of supply voltage in mV. + vcclowwarning |FLOAT |Low Warning Threshold value of supply voltage in mV. + rxpowerhighalarm |FLOAT |High Alarm Threshold value of received power in dBm. + rxpowerlowalarm |FLOAT |Low Alarm Threshold value of received power in dBm. + rxpowerhighwarning |FLOAT |High Warning Threshold value of received power in dBm. + rxpowerlowwarning |FLOAT |Low Warning Threshold value of received power in dBm. + txpowerhighalarm |FLOAT |High Alarm Threshold value of transmit power in dBm. + txpowerlowalarm |FLOAT |Low Alarm Threshold value of transmit power in dBm. + txpowerhighwarning |FLOAT |High Warning Threshold value of transmit power in dBm. + txpowerlowwarning |FLOAT |Low Warning Threshold value of transmit power in dBm. + txbiashighalarm |FLOAT |High Alarm Threshold value of tx Bias Current in mA. + txbiaslowalarm |FLOAT |Low Alarm Threshold value of tx Bias Current in mA. + txbiashighwarning |FLOAT |High Warning Threshold value of tx Bias Current in mA. + txbiaslowwarning |FLOAT |Low Warning Threshold value of tx Bias Current in mA. + ======================================================================== + """ + # check present status + if not self.get_presence(): + return None + + xcvr_dom_threshold_info_dict = dict.fromkeys(self.threshold_dict_keys, 'N/A') + + if self.is_osfp_port: + # Below part is added to avoid fail xcvrd, shall be implemented later + pass + elif self.is_qsfp_port: + # QSFPs + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return None + + dom_thres_raw = self.__read_eeprom_specific_bytes(QSFP_MODULE_THRESHOLD_OFFSET, QSFP_MODULE_THRESHOLD_WIDTH) + + if dom_thres_raw: + module_threshold_values = sfpd_obj.parse_module_threshold_values( + dom_thres_raw, 0) + module_threshold_data = module_threshold_values.get('data') + if module_threshold_data: + xcvr_dom_threshold_info_dict['temphighalarm'] = module_threshold_data['TempHighAlarm']['value'] + xcvr_dom_threshold_info_dict['templowalarm'] = module_threshold_data['TempLowAlarm']['value'] + xcvr_dom_threshold_info_dict['temphighwarning'] = module_threshold_data['TempHighWarning']['value'] + xcvr_dom_threshold_info_dict['templowwarning'] = module_threshold_data['TempLowWarning']['value'] + xcvr_dom_threshold_info_dict['vcchighalarm'] = module_threshold_data['VccHighAlarm']['value'] + xcvr_dom_threshold_info_dict['vcclowalarm'] = module_threshold_data['VccLowAlarm']['value'] + xcvr_dom_threshold_info_dict['vcchighwarning'] = module_threshold_data['VccHighWarning']['value'] + xcvr_dom_threshold_info_dict['vcclowwarning'] = module_threshold_data['VccLowWarning']['value'] + + dom_thres_raw = self.__read_eeprom_specific_bytes(QSFP_CHANNEL_THRESHOLD_OFFSET, QSFP_CHANNEL_THRESHOLD_WIDTH) + if dom_thres_raw: + channel_threshold_values = sfpd_obj.parse_channel_threshold_values( + dom_thres_raw, 0) + channel_threshold_data = channel_threshold_values.get('data') + if channel_threshold_data: + xcvr_dom_threshold_info_dict['rxpowerhighalarm'] = channel_threshold_data['RxPowerHighAlarm']['value'] + xcvr_dom_threshold_info_dict['rxpowerlowalarm'] = channel_threshold_data['RxPowerLowAlarm']['value'] + xcvr_dom_threshold_info_dict['rxpowerhighwarning'] = channel_threshold_data['RxPowerHighWarning']['value'] + xcvr_dom_threshold_info_dict['rxpowerlowwarning'] = channel_threshold_data['RxPowerLowWarning']['value'] + xcvr_dom_threshold_info_dict['txpowerhighalarm'] = "0.0dBm" + xcvr_dom_threshold_info_dict['txpowerlowalarm'] = "0.0dBm" + xcvr_dom_threshold_info_dict['txpowerhighwarning'] = "0.0dBm" + xcvr_dom_threshold_info_dict['txpowerlowwarning'] = "0.0dBm" + xcvr_dom_threshold_info_dict['txbiashighalarm'] = channel_threshold_data['TxBiasHighAlarm']['value'] + xcvr_dom_threshold_info_dict['txbiaslowalarm'] = channel_threshold_data['TxBiasLowAlarm']['value'] + xcvr_dom_threshold_info_dict['txbiashighwarning'] = channel_threshold_data['TxBiasHighWarning']['value'] + xcvr_dom_threshold_info_dict['txbiaslowwarning'] = channel_threshold_data['TxBiasLowWarning']['value'] + + else: + # SFPs + sfpd_obj = sff8472Dom() + offset = 256 + eeprom_ifraw = self.__read_eeprom_specific_bytes(0, offset) + sfpi_obj = sff8472InterfaceId(eeprom_ifraw) + cal_type = sfpi_obj.get_calibration_type() + sfpd_obj._calibration_type = cal_type + + dom_module_threshold_raw = self.__read_eeprom_specific_bytes( + (offset + SFP_MODULE_THRESHOLD_OFFSET), SFP_MODULE_THRESHOLD_WIDTH) + if dom_module_threshold_raw is not None: + dom_module_threshold_data = sfpd_obj.parse_alarm_warning_threshold( + dom_module_threshold_raw, 0) + + xcvr_dom_threshold_info_dict['temphighalarm'] = dom_module_threshold_data['data']['TempHighAlarm']['value'] + xcvr_dom_threshold_info_dict['templowalarm'] = dom_module_threshold_data['data']['TempLowAlarm']['value'] + xcvr_dom_threshold_info_dict['temphighwarning'] = dom_module_threshold_data['data']['TempHighWarning']['value'] + xcvr_dom_threshold_info_dict['templowwarning'] = dom_module_threshold_data['data']['TempLowWarning']['value'] + xcvr_dom_threshold_info_dict['vcchighalarm'] = dom_module_threshold_data['data']['VoltageHighAlarm']['value'] + xcvr_dom_threshold_info_dict['vcclowalarm'] = dom_module_threshold_data['data']['VoltageLowAlarm']['value'] + xcvr_dom_threshold_info_dict['vcchighwarning'] = dom_module_threshold_data['data']['VoltageHighWarning']['value'] + xcvr_dom_threshold_info_dict['vcclowwarning'] = dom_module_threshold_data['data']['VoltageLowWarning']['value'] + xcvr_dom_threshold_info_dict['txbiashighalarm'] = dom_module_threshold_data['data']['BiasHighAlarm']['value'] + xcvr_dom_threshold_info_dict['txbiaslowalarm'] = dom_module_threshold_data['data']['BiasLowAlarm']['value'] + xcvr_dom_threshold_info_dict['txbiashighwarning'] = dom_module_threshold_data['data']['BiasHighWarning']['value'] + xcvr_dom_threshold_info_dict['txbiaslowwarning'] = dom_module_threshold_data['data']['BiasLowWarning']['value'] + xcvr_dom_threshold_info_dict['txpowerhighalarm'] = dom_module_threshold_data['data']['TXPowerHighAlarm']['value'] + xcvr_dom_threshold_info_dict['txpowerlowalarm'] = dom_module_threshold_data['data']['TXPowerLowAlarm']['value'] + xcvr_dom_threshold_info_dict['txpowerhighwarning'] = dom_module_threshold_data['data']['TXPowerHighWarning']['value'] + xcvr_dom_threshold_info_dict['txpowerlowwarning'] = dom_module_threshold_data['data']['TXPowerLowWarning']['value'] + xcvr_dom_threshold_info_dict['rxpowerhighalarm'] = dom_module_threshold_data['data']['RXPowerHighAlarm']['value'] + xcvr_dom_threshold_info_dict['rxpowerlowalarm'] = dom_module_threshold_data['data']['RXPowerLowAlarm']['value'] + xcvr_dom_threshold_info_dict['rxpowerhighwarning'] = dom_module_threshold_data['data']['RXPowerHighWarning']['value'] + xcvr_dom_threshold_info_dict['rxpowerlowwarning'] = dom_module_threshold_data['data']['RXPowerLowWarning']['value'] + + + + return xcvr_dom_threshold_info_dict + + def get_reset_status(self): + """ + Retrieves the reset status of SFP + + Returns: + A Boolean, True if reset enabled, False if disabled + """ + cpld_index = (self.index / CPLD_PORT_NUM) + 1 + index = (self.index % CPLD_PORT_NUM) + 1 + if cpld_index == 5: + # Not support reset for SFP+ + return True + + path = self.port_reset_path + port_path = path.format(self.port_to_i2cbus_mapping[cpld_index], index) + + try: + reg_file = open(port_path) + reg_value = int(reg_file.readline().rstrip(), 16) + + reg_file.close() + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + return reg_value + + def get_rx_los(self): + """ + Retrieves the RX LOS (lost-of-signal) status of SFP + + Returns: + A Boolean, True if SFP has RX LOS, False if not. + Note : RX LOS status is latched until a call to get_rx_los or a reset. + """ + rx_los = None + if not self.get_presence(): + return rx_los + + # read the values from EEPROM + if self.is_osfp_port: + pass + elif self.is_qsfp_port: + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + QSFP_CHANNL_RX_LOS_STATUS_OFFSET, QSFP_CHANNL_RX_LOS_STATUS_WIDTH) if self.get_presence() else None + if dom_channel_monitor_raw is not None: + rx_los_data = int(dom_channel_monitor_raw[0], 16) + rx_los = True if ((rx_los_data & 0xF) == 0xF) else False + else: + # SFP ports + status_control_raw = self.__read_eeprom_specific_bytes( + SFP_STATUS_CONTROL_OFFSET, SFP_STATUS_CONTROL_WIDTH) + if status_control_raw: + data = int(status_control_raw[0], 16) + rx_los = (sffbase().test_bit(data, 1) != 0) + + return rx_los + + def get_tx_fault(self): + """ + Retrieves the TX fault status of SFP + + Returns: + A Boolean, True if SFP has TX fault, False if not + Note : TX fault status is lached until a call to get_tx_fault or a reset. + """ + tx_fault = None + if not self.get_presence(): + return tx_fault + + # read the values from EEPROM + if self.is_osfp_port: + pass + elif self.is_qsfp_port: + dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( + QSFP_CHANNL_TX_FAULT_STATUS_OFFSET, QSFP_CHANNL_TX_FAULT_STATUS_WIDTH) if self.get_presence() else None + if dom_channel_monitor_raw is not None: + tx_fault_data = int(dom_channel_monitor_raw[0], 16) + tx_fault = True if ((tx_fault_data & 0xF) == 0xF) else False + else: + # SFP + status_control_raw = self.__read_eeprom_specific_bytes( + SFP_STATUS_CONTROL_OFFSET, SFP_STATUS_CONTROL_WIDTH) + if status_control_raw: + data = int(status_control_raw[0], 16) + tx_fault = (sffbase().test_bit(data, 2) != 0) + + return tx_fault + + def get_lpmode(self): + """ + Retrieves the lpmode (low power mode) status of this SFP + Returns: + A Boolean, True if lpmode is enabled, False if disabled + """ + index = (self.index % 8) + i2c_index = (self.index / 8) + 1 + path = self.lpmode_path + if i2c_index == 5: + return False + else: + port_path = path.format(self.port_to_i2cbus_mapping[i2c_index], (index + 1)) + + try: + reg_file = open(port_path) + reg_value = int(reg_file.readline().rstrip(), 16) + + reg_file.close() + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + return reg_value + + def reset(self): + """ + Reset SFP and return all user module settings to their default srate. + Returns: + A boolean, True if successful, False if not + """ + cpld_index = (self.index / CPLD_PORT_NUM) + 1 + index = (self.index % CPLD_PORT_NUM) + 1 + if cpld_index == 5: + # Not support reset for SFP+ + return True + else: + path = self.port_reset_path + port_path = path.format(self.port_to_i2cbus_mapping[cpld_index], index) + + try: + reg_file = open(port_path, 'w') + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + # reset + reg_file.write('1') + + time.sleep(1) + + reg_file.write('0') + + reg_file.close() + return True + + def set_lpmode(self, lpmode): + """ + Sets the lpmode (low power mode) of SFP + Args: + lpmode: A Boolean, True to enable lpmode, False to disable it + Note : lpmode can be overridden by set_power_override + Returns: + A boolean, True if lpmode is set successfully, False if not + """ + index = (self.index % 8) + i2c_index = (self.index / 8) + 1 + path = self.lpmode_path + if i2c_index == 5: + raise NotImplementedError + else: + port_path = path.format(self.port_to_i2cbus_mapping[i2c_index], (index + 1)) + + try: + reg_file = open(port_path, 'w') + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + if lpmode == True: + reg_file.write('1') + else: + reg_file.write('0') + + reg_file.close() + return True \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/thermal.py b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/thermal.py new file mode 100755 index 0000000000..ade03f98e7 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/thermal.py @@ -0,0 +1,176 @@ +#!/usr/bin/env python + +############################################################################# +# +# Module contains an implementation of SONiC Platform Base API and +# provides the thermal status which are available in the platform +# +############################################################################# + +import glob +import os.path + +try: + from sonic_platform_base.thermal_base import ThermalBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +class Alpha_Thermal(ThermalBase): + """Platform-specific Thermal class""" + + temp_node_map = { + 1: "/sys/bus/i2c/devices/0-004f/hwmon/", + 2: "/sys/bus/i2c/devices/3-004d/hwmon/", + 3: "/sys/bus/i2c/devices/4-004c/hwmon/" + } + + temp_name_map = { + 1: "lm75-i2c-0-004f", + 2: "lm75-i2c-3-004d", + 3: "lm75-i2c-4-004c" + } + + _high_crital_threshold = 75 + _high_threshold = 60 + _low_threshold = 50 + + def __init__(self, temp_index): + self.index = temp_index + 1 + + if os.path.exists("/sys/bus/i2c/devices/3-004d/hwmon/") == False: + self.temp_node_map = { + 1: "/sys/bus/i2c/devices/0-004f/hwmon/", + 2: "/sys/bus/i2c/devices/18-004d/hwmon/", + 3: "/sys/bus/i2c/devices/19-004c/hwmon/" + } + + self.temp_name_map = { + 1: "lm75-i2c-0-004f", + 2: "lm75-i2c-18-004d", + 3: "lm75-i2c-19-004c" + } + + ThermalBase.__init__(self) + + def get_name(self): + """ + Retrieves the name of the device + + Returns: + string: The name of the device + """ + return self.temp_name_map[self.index] + + def get_status(self): + """ + Retrieves the operational status of the device + + Returns: + A boolean value, True if device is operating properly, False if not + """ + if self.get_temperature() == -255: + return False + return True + + def get_presence(self): + """ + Retrieves the presence of the device + + Returns: + bool: True if device is present, False if not + """ + node = glob.glob(self.temp_node_map[self.index] + "hwmon*") + if len(node) == 0: + return False + node = node[0] + "/temp1_input" + if os.path.exists(node): + return True + return False + + def get_temperature(self): + """ + Retrieves current temperature reading from thermal + + Returns: + A float number of current temperature in Celsius up to nearest thousandth + of one degree Celsius, e.g. 30.125 + """ + temp = 0 + node = glob.glob(self.temp_node_map[self.index] + "hwmon*") + if len(node) == 0: + return -255 + node = node[0] + "/temp1_input" + try: + with open(node, 'r') as fp: + temp = float(fp.read()) / 1000 + except IOError: + temp = -255 + return temp + + def get_high_threshold(self): + """ + Retrieves the high threshold temperature of thermal + + Returns: + A float number, the high threshold temperature of thermal in Celsius + up to nearest thousandth of one degree Celsius, e.g. 30.125 + """ + return self._high_threshold + + def get_low_threshold(self): + """ + Retrieves the low threshold temperature of thermal + + Returns: + A float number, the low threshold temperature of thermal in Celsius + up to nearest thousandth of one degree Celsius, e.g. 30.125 + """ + return self._low_threshold + + def set_high_threshold(self, temperature): + """ + Sets the high threshold temperature of thermal + + Args : + temperature: A float number up to nearest thousandth of one degree Celsius, + e.g. 30.125 + + Returns: + A boolean, True if threshold is set successfully, False if not + """ + self._high_threshold = temperature + return True + + def set_low_threshold(self, temperature): + """ + Sets the low threshold temperature of thermal + + Args : + temperature: A float number up to nearest thousandth of one degree Celsius, + e.g. 30.125 + + Returns: + A boolean, True if threshold is set successfully, False if not + """ + self._low_threshold = temperature + return True + + def get_high_critical_threshold(self): + """ + Retrieves the high critical threshold temperature of thermal + + Returns: + A float number, the high critical threshold temperature of thermal in Celsius + up to nearest thousandth of one degree Celsius, e.g. 30.125 + """ + return self._high_crital_threshold + + def get_low_critical_threshold(self): + """ + Retrieves the low critical threshold temperature of thermal + + Returns: + A float number, the low critical threshold temperature of thermal in Celsius + up to nearest thousandth of one degree Celsius, e.g. 30.125 + """ + return 0 \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/thermal_actions.py b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/thermal_actions.py new file mode 100755 index 0000000000..480115ce87 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/thermal_actions.py @@ -0,0 +1,93 @@ +from sonic_platform_base.sonic_thermal_control.thermal_action_base import ThermalPolicyActionBase +from sonic_platform_base.sonic_thermal_control.thermal_json_object import thermal_json_object +from sonic_daemon_base.daemon_base import Logger + +__all__ = [ +"SetAllFanSpeedMaxAction", +"SetAllFanSpeedDefaultAction", +"ThermalRecoverAction", +"SwitchPolicyAction", +] + +logger = Logger('alpha') + +class SetFanSpeedAction(ThermalPolicyActionBase): + """ + Base thermal action class to set speed for fans + """ + @classmethod + def set_all_fan_speed(cls, thermal_info_dict, speed): + from .thermal_infos import FanInfo + if FanInfo.INFO_NAME in thermal_info_dict and isinstance(thermal_info_dict[FanInfo.INFO_NAME], FanInfo): + fan_info_obj = thermal_info_dict[FanInfo.INFO_NAME] + for fan in fan_info_obj.get_presence_fans(): + fan.set_speed(speed) + + +@thermal_json_object('fan.all.set_speed_max') +class SetAllFanSpeedMaxAction(SetFanSpeedAction): + """ + Action to set max speed for all fans + """ + def execute(self, thermal_info_dict): + """ + Set max speed for all fans + :param thermal_info_dict: A dictionary stores all thermal information. + :return: + """ + max_speed = 100 + SetAllFanSpeedMaxAction.set_all_fan_speed(thermal_info_dict, max_speed) + +@thermal_json_object('fan.all.set_speed_default') +class SetAllFanSpeedDefaultAction(SetFanSpeedAction): + """ + Action to set default speed for all fans + """ + def execute(self, thermal_info_dict): + """ + Set default speed for all fans + :param thermal_info_dict: A dictionary stores all thermal information. + :return: + """ + default_speed = 50 + SetAllFanSpeedDefaultAction.set_all_fan_speed(thermal_info_dict, default_speed) + + +@thermal_json_object('thermal.temp_check_and_set_all_fan_speed') +class ThermalRecoverAction(SetFanSpeedAction): + """ + Action to check thermal sensor temperature change status and set speed for all fans + """ + def execute(self, thermal_info_dict): + """ + Check check thermal sensor temperature change status and set speed for all fans + :param thermal_info_dict: A dictionary stores all thermal information. + :return: + """ + default_speed = 50 + max_speed = 100 + from .thermal_infos import ThermalInfo + if ThermalInfo.INFO_NAME in thermal_info_dict and isinstance(thermal_info_dict[ThermalInfo.INFO_NAME], ThermalInfo): + thermal_info_obj = thermal_info_dict[ThermalInfo.INFO_NAME] + if thermal_info_obj.is_warm_up_and_over_high_threshold(): + ThermalRecoverAction.set_all_fan_speed(thermal_info_dict, max_speed) + elif thermal_info_obj.is_cold_down_and_below_low_threshold(): + ThermalRecoverAction.set_all_fan_speed(thermal_info_dict, default_speed) + + +@thermal_json_object('switch.shutdown') +class SwitchPolicyAction(ThermalPolicyActionBase): + """ + Base class for thermal action. Once all thermal conditions in a thermal policy are matched, + all predefined thermal action will be executed. + """ + def execute(self, thermal_info_dict): + """ + Take action when thermal condition matches. For example, adjust speed of fan or shut + down the switch. + :param thermal_info_dict: A dictionary stores all thermal information. + :return: + """ + logger.log_warning("Alarm for temperature critical is detected, reboot DUT") + # import os + # os.system('reboot') diff --git a/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/thermal_conditions.py b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/thermal_conditions.py new file mode 100755 index 0000000000..4fa22eac0e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/thermal_conditions.py @@ -0,0 +1,77 @@ +from sonic_platform_base.sonic_thermal_control.thermal_condition_base import ThermalPolicyConditionBase +from sonic_platform_base.sonic_thermal_control.thermal_json_object import thermal_json_object + +__all__ = [ +"AnyFanAbsenceCondition", +"AllFanAbsenceCondition", +"AllFanPresenceCondition", +"AnyFanFaultCondition", +"AllFanGoodCondition", +"AnyFanPresenceChangeCondition", +"ThermalOverHighCriticalCondition", +] + +class FanCondition(ThermalPolicyConditionBase): + def get_fan_info(self, thermal_info_dict): + from .thermal_infos import FanInfo + if FanInfo.INFO_NAME in thermal_info_dict and isinstance(thermal_info_dict[FanInfo.INFO_NAME], FanInfo): + return thermal_info_dict[FanInfo.INFO_NAME] + else: + return None + + +@thermal_json_object('fan.any.absence') +class AnyFanAbsenceCondition(FanCondition): + def is_match(self, thermal_info_dict): + fan_info_obj = self.get_fan_info(thermal_info_dict) + return len(fan_info_obj.get_absence_fans()) > 0 if fan_info_obj else False + + +@thermal_json_object('fan.all.absence') +class AllFanAbsenceCondition(FanCondition): + def is_match(self, thermal_info_dict): + fan_info_obj = self.get_fan_info(thermal_info_dict) + return len(fan_info_obj.get_presence_fans()) == 0 if fan_info_obj else False + + +@thermal_json_object('fan.all.presence') +class AllFanPresenceCondition(FanCondition): + def is_match(self, thermal_info_dict): + fan_info_obj = self.get_fan_info(thermal_info_dict) + return len(fan_info_obj.get_absence_fans()) == 0 if fan_info_obj else False + + +@thermal_json_object('fan.any.fault') +class AnyFanFaultCondition(FanCondition): + def is_match(self, thermal_info_dict): + fan_info_obj = self.get_fan_info(thermal_info_dict) + return len(fan_info_obj.get_fault_fans()) > 0 if fan_info_obj else False + + +@thermal_json_object('fan.all.good') +class AllFanGoodCondition(FanCondition): + def is_match(self, thermal_info_dict): + fan_info_obj = self.get_fan_info(thermal_info_dict) + return len(fan_info_obj.get_fault_fans()) == 0 if fan_info_obj else False + +@thermal_json_object('fan.any.presence.change') +class AnyFanPresenceChangeCondition(FanCondition): + def is_match(self, thermal_info_dict): + fan_info_obj = self.get_fan_info(thermal_info_dict) + return fan_info_obj.is_presence_changed() if fan_info_obj else False + + +class ThermalCondition(ThermalPolicyConditionBase): + def get_thermal_info(self, thermal_info_dict): + from .thermal_infos import ThermalInfo + if ThermalInfo.INFO_NAME in thermal_info_dict and isinstance(thermal_info_dict[ThermalInfo.INFO_NAME], ThermalInfo): + return thermal_info_dict[ThermalInfo.INFO_NAME] + else: + return None + + +@thermal_json_object('thermal.over.high_critical_threshold') +class ThermalOverHighCriticalCondition(ThermalCondition): + def is_match(self, thermal_info_dict): + thermal_info_obj = self.get_thermal_info(thermal_info_dict) + return thermal_info_obj.is_over_high_critical_threshold() if thermal_info_obj else False diff --git a/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/thermal_infos.py b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/thermal_infos.py new file mode 100755 index 0000000000..011eba2048 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/thermal_infos.py @@ -0,0 +1,183 @@ +from sonic_platform_base.sonic_thermal_control.thermal_info_base import ThermalPolicyInfoBase +from sonic_platform_base.sonic_thermal_control.thermal_json_object import thermal_json_object + +__all__ = [ +"FanInfo", +"ThermalInfo", +"ChassisInfo", +] + +@thermal_json_object('fan_info') +class FanInfo(ThermalPolicyInfoBase): + """ + Fan information needed by thermal policy + """ + + # Fan information name + INFO_NAME = 'fan_info' + + def __init__(self): + self._absence_fans = set() + self._presence_fans = set() + self._fault_fans = set() + self._presence_changed = False + self._status_changed = False + + def collect(self, chassis): + """ + Collect absence and presence fans. + :param chassis: The chassis object + :return: + """ + self._presence_changed = False + self._status_changed = False + for fan in chassis.get_all_fans(): + presence = fan.get_presence() + status = fan.get_status() + if presence and fan not in self._presence_fans: + self._presence_fans.add(fan) + self._presence_changed = True + if fan in self._absence_fans: + self._absence_fans.remove(fan) + elif not presence and fan not in self._absence_fans: + self._absence_fans.add(fan) + self._presence_changed = True + if fan in self._presence_fans: + self._presence_fans.remove(fan) + + if not status and fan not in self._fault_fans: + self._fault_fans.add(fan) + self._status_changed = True + elif status and fan in self._fault_fans: + self._fault_fans.remove(fan) + self._status_changed = True + + + def get_absence_fans(self): + """ + Retrieves absence fans + :return: A set of absence fans + """ + return self._absence_fans + + def get_presence_fans(self): + """ + Retrieves presence fans + :return: A set of presence fans + """ + return self._presence_fans + + def get_fault_fans(self): + """ + Retrieves fault fans + :return: A set of fault fans + """ + return self._fault_fans + + def is_presence_changed(self): + """ + Retrieves if the presence status of fan information changed + :return: True if status changed else False + """ + return self._presence_changed + + +@thermal_json_object('thermal_info') +class ThermalInfo(ThermalPolicyInfoBase): + """ + Thermal information needed by thermal policy + """ + + # Fan information name + INFO_NAME = 'thermal_info' + + def __init__(self): + + self.init = False + self._old_avg_temp = 0 + self._current_avg_temp = 0 + self._high_crital_threshold = 75 + self._high_threshold = 60 + self._low_threshold = 50 + self._thermal_0x4d_index = 1 + + def collect(self, chassis): + """ + Collect thermal sensor temperature change status + :param chassis: The chassis object + :return: + """ + + self._temps = [] + self._over_high_critical_threshold = False + self._warm_up_and_over_high_threshold = False + self._cold_down_and_below_low_threshold = False + + temp = 0 + num_of_thermals = chassis.get_num_thermals() + for index in range(num_of_thermals): + self._temps.insert(index, chassis.get_thermal(index).get_temperature()) + temp += self._temps[index] + + self._current_avg_temp = temp / num_of_thermals + if self.init == False: + self._old_avg_temp = self._current_avg_temp + self.init = True + + if self._current_avg_temp >= self._old_avg_temp and self._current_avg_temp >= self._high_threshold: + self._warm_up_and_over_high_threshold = True + + if self._current_avg_temp <= self._old_avg_temp and self._current_avg_temp <= self._low_threshold: + self._cold_down_and_below_low_threshold = True + + if self._temps[self._thermal_0x4d_index] >= self._high_crital_threshold: + self._over_high_critical_threshold = True + + self._old_avg_temp = self._current_avg_temp + + def is_warm_up_and_over_high_threshold(self): + """ + Retrieves if the temperature is warm up and over high threshold + :return: True if the temperature is warm up and over high threshold else False + """ + return self._warm_up_and_over_high_threshold + + def is_cold_down_and_below_low_threshold(self): + """ + Retrieves if the temperature is cold down and below low threshold + :return: True if the temperature is cold down and below low threshold else False + """ + return self._cold_down_and_below_low_threshold + + def is_over_high_critical_threshold(self): + """ + Retrieves if the temperature is over high critical threshold + :return: True if the temperature is over high critical threshold else False + """ + return self._over_high_critical_threshold + + +@thermal_json_object('chassis_info') +class ChassisInfo(ThermalPolicyInfoBase): + """ + Chassis information needed by thermal policy + """ + INFO_NAME = 'chassis_info' + + def __init__(self): + self._chassis = None + + def collect(self, chassis): + """ + Collect platform chassis. + :param chassis: The chassis object + :return: + """ + self._chassis = chassis + + def get_chassis(self): + """ + Retrieves platform chassis object + :return: A platform chassis object. + """ + return self._chassis \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/thermal_manager.py b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/thermal_manager.py new file mode 100755 index 0000000000..c062256576 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/sonic_platform/thermal_manager.py @@ -0,0 +1,23 @@ +from sonic_platform_base.sonic_thermal_control.thermal_manager_base import ThermalManagerBase +from .thermal_infos import * # lgtm[py/polluting-import] +from .thermal_conditions import * # lgtm[py/polluting-import] +from .thermal_actions import * # lgtm[py/polluting-import] + +class ThermalManager(ThermalManagerBase): + @classmethod + def initialize(cls): + """ + Initialize thermal manager, including register thermal condition types and thermal action types + and any other vendor specific initialization. + :return: + """ + return True + + @classmethod + def deinitialize(cls): + """ + Destroy thermal manager, including any vendor specific cleanup. The default behavior of this function + is a no-op. + :return: + """ + return True diff --git a/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/utils/alphanetworks_snj60b0_util.py b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/utils/alphanetworks_snj60b0_util.py new file mode 100755 index 0000000000..06bb7a6f07 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-alphanetworks/snj60b0-320f/utils/alphanetworks_snj60b0_util.py @@ -0,0 +1,521 @@ +#!/usr/bin/env python +# +# Copyright (C) 2019 Alphanetworks Technology Corporation. +# Robin Chen +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# see +# +# Copyright (C) 2016 Accton Networks, Inc. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +""" +Usage: %(scriptName)s [options] command object + +options: + -h | --help : this help message + -d | --debug : run with debug mode + -f | --force : ignore error during installation or clean +command: + install : install drivers and generate related sysfs nodes + clean : uninstall drivers and remove related sysfs nodes +""" + +import commands +import sys, getopt +import logging +import time + + +PROJECT_NAME = 'snj60b0-320f' +DRIVER_NAME = 'snj60b0_320f' +device_path = "x86_64-alphanetworks_snj60b0_320f-r0" +version = '0.1.0' +verbose = False +DEBUG = False +args = [] +FORCE = 0 + +devMaxPort = 34 +cpldPortNum = 8 + +FPGAAddr = "005e" +PortCPLD_Addr = "005f" + +portFPGAAddr = "0x5e" +portCPLDAddr = "0x5f" +portAddr = "0x50" + +if DEBUG == True: + print sys.argv[0] + print 'ARGV :', sys.argv[1:] + + +def main(): + global DEBUG + global args + global FORCE + + if len(sys.argv)<2: + show_help() + + options, args = getopt.getopt(sys.argv[1:], 'hdf', ['help', + 'debug', + 'force', + ]) + if DEBUG == True: + print options + print args + print len(sys.argv) + + for opt, arg in options: + if opt in ('-h', '--help'): + show_help() + elif opt in ('-d', '--debug'): + DEBUG = True + logging.basicConfig(level=logging.INFO) + elif opt in ('-f', '--force'): + FORCE = 1 + else: + logging.info('no option') + for arg in args: + if arg == 'install': + do_install() + elif arg == 'clean': + do_uninstall() + else: + show_help() + + + return 0 + +def show_help(): + print __doc__ % {'scriptName' : sys.argv[0].split("/")[-1]} + sys.exit(0) + +def show_log(txt): + if DEBUG == True: + print PROJECT_NAME.upper()+": "+txt + return + +def log_os_system(cmd, show): + logging.info('Run :'+cmd) + status, output = commands.getstatusoutput(cmd) + show_log (cmd +" with result: " + str(status)) + show_log (" output:"+output) + if status: + logging.info('Failed :'+cmd) + if show: + print('Failed :'+cmd) + return status, output + +def driver_check(): + ret, lsmod = log_os_system("lsmod | grep " + DRIVER_NAME, 0) + logging.info('mods:'+lsmod) + if len(lsmod) ==0: + return False + return True + + + +kos = [ +'modprobe i2c_ismt', +'modprobe i2c_i801', +'modprobe i2c_dev', +'modprobe i2c_mux_pca954x', +'modprobe optoe', +'modprobe yesm1300am', +'modprobe '+PROJECT_NAME+'_fpga' , +'modprobe '+PROJECT_NAME+'_onie_eeprom' , +'modprobe '+PROJECT_NAME+'_sfp' ] + +def driver_install(): + global FORCE + status, output = log_os_system("depmod", 1) + if status: + if FORCE == 0: + return status + for i in range(0,len(kos)): + if kos[i].find('pca954') != -1: + status, output = log_os_system(kos[i]+ " force_deselect_on_exit=1", 1) + else: + status, output = log_os_system(kos[i], 1) + if status: + if FORCE == 0: + return status + return 0 + +def driver_uninstall(): + global FORCE + for i in range(0,len(kos)): + rm = kos[-(i+1)].replace("modprobe", "modprobe -rq") + rm = rm.replace("insmod", "rmmod") + status, output = log_os_system(rm, 1) + if status: + if FORCE == 0: + return status + return 0 + +i2c_prefix = '/sys/bus/i2c/devices/' + +sfp_map = [13,14,15,16,12,11] +sfp_map2 = [14,15,16,17,13,12] + +mknod =[ +'echo pca9548 0x70 > /sys/bus/i2c/devices/i2c-0/new_device', +'echo pca9545 0x71 > /sys/bus/i2c/devices/i2c-5/new_device', +'echo pca9548 0x72 > /sys/bus/i2c/devices/i2c-7/new_device', +'echo pca9548 0x73 > /sys/bus/i2c/devices/i2c-20/new_device', +'echo 24c02 0x50 > /sys/bus/i2c/devices/i2c-9/new_device', +'echo 24c02 0x51 > /sys/bus/i2c/devices/i2c-10/new_device', +'echo snj60b0_onie_eeprom 0x56 > /sys/bus/i2c/devices/i2c-0/new_device', +'echo snj60b0_fpga 0x5e > /sys/bus/i2c/devices/i2c-0/new_device', +'echo lm75 0x4D > /sys/bus/i2c/devices/i2c-3/new_device', +'echo lm75 0x4C > /sys/bus/i2c/devices/i2c-4/new_device', +'echo lm75 0x4F > /sys/bus/i2c/devices/i2c-0/new_device', +'echo yesm1300am 0x58 > /sys/bus/i2c/devices/i2c-9/new_device', +'echo yesm1300am 0x59 > /sys/bus/i2c/devices/i2c-10/new_device' ] + +mknod2 =[ +'echo pca9548 0x70 > /sys/bus/i2c/devices/i2c-1/new_device', +'echo pca9545 0x71 > /sys/bus/i2c/devices/i2c-6/new_device', +'echo pca9548 0x72 > /sys/bus/i2c/devices/i2c-8/new_device', +'echo pca9548 0x73 > /sys/bus/i2c/devices/i2c-21/new_device', +'echo 24c02 0x50 > /sys/bus/i2c/devices/i2c-10/new_device', +'echo 24c02 0x51 > /sys/bus/i2c/devices/i2c-11/new_device', +'echo snj60b0_onie_eeprom 0x56 > /sys/bus/i2c/devices/i2c-1/new_device', +'echo snj60b0_fpga 0x5e > /sys/bus/i2c/devices/i2c-1/new_device', +'echo lm75 0x4D > /sys/bus/i2c/devices/i2c-4/new_device', +'echo lm75 0x4C > /sys/bus/i2c/devices/i2c-5/new_device', +'echo lm75 0x4F > /sys/bus/i2c/devices/i2c-1/new_device', +'echo yesm1300am 0x58 > /sys/bus/i2c/devices/i2c-10/new_device', +'echo yesm1300am 0x59 > /sys/bus/i2c/devices/i2c-11/new_device' ] + + + +def i2c_order_check(): + # i2c bus 0 and 1 might be installed in different order. + # Here check if 0x76 is exist @ i2c-0 + + status, output = log_os_system("i2cdetect -l | grep I801 | grep i2c-0", 0) + if not output: + order = 1 + tmp = "sed -i 's/0-/1-/g' /usr/share/sonic/device/"+device_path+"/plugins/led_control.py" + else: + order = 0 + tmp = "sed -i 's/1-/0-/g' /usr/share/sonic/device/"+device_path+"/plugins/led_control.py" + status, output = log_os_system(tmp, 0) + if status: + print output + if FORCE == 0: + return status + return order + +def device_install(): + global FORCE + global devMaxPort + global cpldPortNum + + order = i2c_order_check() + + # if 0x76 is not exist @i2c-0, use reversed bus order + if order: + for i in range(0,len(mknod2)): + #for pca954x need times to built new i2c buses + if mknod2[i].find('pca954') != -1: + time.sleep(1) + + if mknod2[i].find('lm75') != -1: + time.sleep(1) + + status, output = log_os_system(mknod2[i], 1) + if status: + print output + if FORCE == 0: + return status + status, output =log_os_system("echo 0 > /sys/bus/i2c/devices/1-"+FPGAAddr+"/sys_reset1", 1) + if status: + print output + if FORCE == 0: + return status + + status, output =log_os_system("echo 4 > /sys/bus/i2c/devices/1-"+FPGAAddr+"/sys_reset2", 1) + if status: + print output + if FORCE == 0: + return status + else: + for i in range(0,len(mknod)): + #for pca954x need times to built new i2c buses + if mknod[i].find('pca954') != -1: + time.sleep(1) + + if mknod[i].find('lm75') != -1: + time.sleep(1) + + status, output = log_os_system(mknod[i], 1) + if status: + print output + if FORCE == 0: + return status + status, output =log_os_system("echo 0 > /sys/bus/i2c/devices/0-"+FPGAAddr+"/sys_reset1", 1) + if status: + print output + if FORCE == 0: + return status + + status, output =log_os_system("echo 4 > /sys/bus/i2c/devices/0-"+FPGAAddr+"/sys_reset2", 1) + if status: + print output + if FORCE == 0: + return status + + for i in range(0, devMaxPort): + index = i / cpldPortNum + port = i % cpldPortNum + reg_sfp = 0 + if port == 0: + reg_sfp = 1 + +# Port CPLD and FPGA device add + if reg_sfp == 1: + if i < 32: + if order: + status, output =log_os_system("echo sfpcpld"+str(i+1)+" "+portCPLDAddr+" > /sys/bus/i2c/devices/i2c-"+str(sfp_map2[index])+"/new_device", 1) + else: + status, output =log_os_system("echo sfpcpld"+str(i+1)+" "+portCPLDAddr+" > /sys/bus/i2c/devices/i2c-"+str(sfp_map[index])+"/new_device", 1) + if status: + print output + if FORCE == 0: + return status +# Front port EEPROM device add + if order: + status, output =log_os_system("echo sfpcpld"+str(i+1)+" "+portAddr+" > /sys/bus/i2c/devices/i2c-"+str(sfp_map2[index])+"/new_device", 1) + else: + status, output =log_os_system("echo sfpcpld"+str(i+1)+" "+portAddr+" > /sys/bus/i2c/devices/i2c-"+str(sfp_map[index])+"/new_device", 1) + if status: + print output + if FORCE == 0: + return status + +# Port EEPROM device add + if i == 32: + if order: + status, output =log_os_system("echo sfpcpld"+str(i+1)+" "+portAddr+" > /sys/bus/i2c/devices/i2c-"+str(sfp_map2[index])+"/new_device", 1) + else: + status, output =log_os_system("echo sfpcpld"+str(i+1)+" "+portAddr+" > /sys/bus/i2c/devices/i2c-"+str(sfp_map[index])+"/new_device", 1) + + if status: + print output + if FORCE == 0: + return status + if i == 33: + if order: + status, output =log_os_system("echo sfpcpld"+str(i+1)+" "+portAddr+" > /sys/bus/i2c/devices/i2c-"+str(sfp_map2[index+1])+"/new_device", 1) + else: + status, output =log_os_system("echo sfpcpld"+str(i+1)+" "+portAddr+" > /sys/bus/i2c/devices/i2c-"+str(sfp_map[index+1])+"/new_device", 1) + if status: + print output + if FORCE == 0: + return status +# Front port LED enable + if order: + status, output =log_os_system("echo 0 > /sys/bus/i2c/devices/1-"+FPGAAddr+"/port_led_disable", 1) + else: + status, output =log_os_system("echo 0 > /sys/bus/i2c/devices/0-"+FPGAAddr+"/port_led_disable", 1) + if status: + print output + if FORCE == 0: + return status + + if order: + for i in [0,1,2,3]: + status, output =log_os_system("echo 0 > /sys/bus/i2c/devices/"+str(sfp_map2[i])+"-"+PortCPLD_Addr+"/sfp_led_disable", 1) + if status: + if FORCE == 0: + return status + else: + for i in [0,1,2,3]: + status, output =log_os_system("echo 0 > /sys/bus/i2c/devices/"+str(sfp_map[i])+"-"+PortCPLD_Addr+"/sfp_led_disable", 1) + if status: + if FORCE == 0: + return status +# end of Front port LED enable + + return + +def device_uninstall(): + global FORCE + + status, output =log_os_system("ls /sys/bus/i2c/devices/1-0070", 0) + if status==0: + I2C_ORDER=1 + else: + I2C_ORDER=0 + +# Front port LED disable + if I2C_ORDER: + status, output =log_os_system("echo 1 > /sys/bus/i2c/devices/1-"+FPGAAddr+"/port_led_disable", 1) + else: + status, output =log_os_system("echo 1 > /sys/bus/i2c/devices/0-"+FPGAAddr+"/port_led_disable", 1) + if status: + print output + if FORCE == 0: + return status + + if I2C_ORDER: + for i in [0,1,2,3]: + status, output =log_os_system("echo 1 > /sys/bus/i2c/devices/"+str(sfp_map2[i])+"-"+PortCPLD_Addr+"/sfp_led_disable", 1) + if status: + if FORCE == 0: + return status + else: + for i in [0,1,2,3]: + status, output =log_os_system("echo 1 > /sys/bus/i2c/devices/"+str(sfp_map[i])+"-"+PortCPLD_Addr+"/sfp_led_disable", 1) + if status: + if FORCE == 0: + return status +# end of Front port LED disable + + + for i in range(0, devMaxPort): + index = i / cpldPortNum + port = i % cpldPortNum + reg_sfp = 0 + if port == 0: + reg_sfp = 1 + + if reg_sfp == 1: + if i < 32: + if I2C_ORDER: + target = "/sys/bus/i2c/devices/i2c-"+str(sfp_map2[index])+"/delete_device" + else: + target = "/sys/bus/i2c/devices/i2c-"+str(sfp_map[index])+"/delete_device" + status, output =log_os_system("echo "+portCPLDAddr+" > "+ target, 1) + if status: + print output + if FORCE == 0: + return status + + if I2C_ORDER: + target = "/sys/bus/i2c/devices/i2c-"+str(sfp_map2[index])+"/delete_device" + else: + target = "/sys/bus/i2c/devices/i2c-"+str(sfp_map[index])+"/delete_device" + status, output =log_os_system("echo "+portAddr+" > "+ target, 1) + if status: + print output + if FORCE == 0: + return status + + if i == 32: + if I2C_ORDER: + status, output =log_os_system("echo 0x50 > /sys/bus/i2c/devices/i2c-"+str(sfp_map2[index])+"/delete_device", 1) + else: + status, output =log_os_system("echo 0x50 > /sys/bus/i2c/devices/i2c-"+str(sfp_map[index])+"/delete_device", 1) + if status: + print output + if FORCE == 0: + return status + if i == 33: + if I2C_ORDER: + status, output =log_os_system("echo 0x50 > /sys/bus/i2c/devices/i2c-"+str(sfp_map2[index+1])+"/delete_device", 1) + else: + status, output =log_os_system("echo 0x50 > /sys/bus/i2c/devices/i2c-"+str(sfp_map[index+1])+"/delete_device", 1) + if status: + print output + if FORCE == 0: + return status + + if I2C_ORDER: + nodelist = mknod2 + else: + nodelist = mknod + + for i in range(len(nodelist)): + target = nodelist[-(i+1)] + temp = target.split() + del temp[1] + temp[-1] = temp[-1].replace('new_device', 'delete_device') + status, output = log_os_system(" ".join(temp), 1) + if status: + print output + if FORCE == 0: + return status + + return + +def system_ready(): + if driver_check() == False: + return False + if not device_exist(): + return False + return True + +def do_install(): + print "Checking system...." + if driver_check() == False: + print "No driver, installing...." + status = driver_install() + if status: + if FORCE == 0: + return status + else: + print PROJECT_NAME.upper()+" drivers detected...." + if not device_exist(): + print "No device, installing...." + status = device_install() + if status: + if FORCE == 0: + return status + else: + print PROJECT_NAME.upper()+" devices detected...." + return + +def do_uninstall(): + print "Checking system...." + if not device_exist(): + print PROJECT_NAME.upper() +" has no device installed...." + else: + print "Removing device...." + status = device_uninstall() + if status: + if FORCE == 0: + return status + + if driver_check()== False : + print PROJECT_NAME.upper() +" has no driver installed...." + else: + print "Removing installed driver...." + status = driver_uninstall() + if status: + if FORCE == 0: + return status + + return + +def device_exist(): + ret1, log = log_os_system("ls "+i2c_prefix+"*0070", 0) + ret2, log = log_os_system("ls "+i2c_prefix+"i2c-2", 0) + return not(ret1 or ret2) + +if __name__ == "__main__": + main()