get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/44399/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 44399,
    "url": "http://patches.dpdk.org/api/patches/44399/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/1536333719-32155-7-git-send-email-igor.russkikh@aquantia.com/",
    "project": {
        "id": 1,
        "url": "http://patches.dpdk.org/api/projects/1/?format=api",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<1536333719-32155-7-git-send-email-igor.russkikh@aquantia.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1536333719-32155-7-git-send-email-igor.russkikh@aquantia.com",
    "date": "2018-09-07T15:21:44",
    "name": "[06/21] net/atlantic: firmware operations layer",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "1bd7dc727c958e667457a1da34bb83c11e142370",
    "submitter": {
        "id": 1124,
        "url": "http://patches.dpdk.org/api/people/1124/?format=api",
        "name": "Igor Russkikh",
        "email": "igor.russkikh@aquantia.com"
    },
    "delegate": {
        "id": 319,
        "url": "http://patches.dpdk.org/api/users/319/?format=api",
        "username": "fyigit",
        "first_name": "Ferruh",
        "last_name": "Yigit",
        "email": "ferruh.yigit@amd.com"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/1536333719-32155-7-git-send-email-igor.russkikh@aquantia.com/mbox/",
    "series": [
        {
            "id": 1228,
            "url": "http://patches.dpdk.org/api/series/1228/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=1228",
            "date": "2018-09-07T15:21:39",
            "name": "net/atlantic: Aquantia aQtion 10G NIC Family DPDK PMD driver",
            "version": 1,
            "mbox": "http://patches.dpdk.org/series/1228/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/44399/comments/",
    "check": "fail",
    "checks": "http://patches.dpdk.org/api/patches/44399/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@dpdk.org",
        "Delivered-To": "patchwork@dpdk.org",
        "Received": [
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id DB5CE58C4;\n\tFri,  7 Sep 2018 17:23:28 +0200 (CEST)",
            "from NAM03-BY2-obe.outbound.protection.outlook.com\n\t(mail-by2nam03on0044.outbound.protection.outlook.com [104.47.42.44])\n\tby dpdk.org (Postfix) with ESMTP id CFDC34C8D\n\tfor <dev@dpdk.org>; Fri,  7 Sep 2018 17:23:20 +0200 (CEST)",
            "from ubuntubox.rdc.aquantia.com (95.79.108.179) by\n\tBLUPR0701MB1652.namprd07.prod.outlook.com (2a01:111:e400:58c6::22)\n\twith Microsoft SMTP Server (version=TLS1_2,\n\tcipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.1122.16;\n\tFri, 7 Sep 2018 15:23:12 +0000"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=AQUANTIA1COM.onmicrosoft.com; s=selector1-aquantia-com;\n\th=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck;\n\tbh=3qOeBgXZvQfv66SUO2Y+Lh6em7peI8Ou6Ah3eUpDX2w=;\n\tb=my63DJY+FP2f9wmzsvG2I7AjrZ1znAMDumqXlMrNHiCvOdCWI9Q015+tWMWh9Cmq/u/iJrfirAG+AmEMD/5d9Jn1ow4NbnzhTyAmhx83+abTtJb3fkyQGC18UUyI8NgcAOjj5tuM1FfwQBMoaPvDShp8oesaqT7nd3O+znxpJak=",
        "Authentication-Results": "spf=none (sender IP is )\n\tsmtp.mailfrom=Igor.Russkikh@aquantia.com; ",
        "From": "Igor Russkikh <igor.russkikh@aquantia.com>",
        "To": "dev@dpdk.org",
        "Cc": "pavel.belous@aquantia.com, Nadezhda.Krupnina@aquantia.com,\n\tigor.russkikh@aquantia.com, Simon.Edelhaus@aquantia.com,\n\tCorey Melton <comelton@cisco.com>, Ashish Kumar <ashishk2@cisco.com>",
        "Date": "Fri,  7 Sep 2018 18:21:44 +0300",
        "Message-Id": "<1536333719-32155-7-git-send-email-igor.russkikh@aquantia.com>",
        "X-Mailer": "git-send-email 2.7.4",
        "In-Reply-To": "<1536333719-32155-1-git-send-email-igor.russkikh@aquantia.com>",
        "References": "<1536333719-32155-1-git-send-email-igor.russkikh@aquantia.com>",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain",
        "X-Originating-IP": "[95.79.108.179]",
        "X-ClientProxiedBy": "BN6PR20CA0060.namprd20.prod.outlook.com\n\t(2603:10b6:404:151::22) To BLUPR0701MB1652.namprd07.prod.outlook.com\n\t(2a01:111:e400:58c6::22)",
        "X-MS-PublicTrafficType": "Email",
        "X-MS-Office365-Filtering-Correlation-Id": "042ca868-2f8d-4c38-0808-08d614d5d401",
        "X-Microsoft-Antispam": "BCL:0; PCL:0;\n\tRULEID:(7020095)(4652040)(8989137)(4534165)(4627221)(201703031133081)(201702281549075)(8990107)(5600074)(711020)(2017052603328)(7153060)(7193020);\n\tSRVR:BLUPR0701MB1652; ",
        "X-Microsoft-Exchange-Diagnostics": [
            "1; BLUPR0701MB1652;\n\t3:2+tJlVi7JkeSBL8EqKo8L+37IXlqqWmMRmn296kXX9PbrpYCPs9yShV8JIHq4C5Vh/F4T7ClFd5L5Sl1wWK+EZgZ0IvBi+w697kBYMHB74YV8BRFJ1Zyc6eLIRAN77FUPeKkPx1qCSefe0Lr7xO1563nEHfzWokTRU7wabKAarE/iOBoojTTtw2Ej8MouelVFFoEi58Si5p6O1RGQoM6I10Ex7AkZnGrwSY7vq8smuDr5l3ZRhtlNoBV49D6/Rvj;\n\t25:As5+0aRjxPzAbGSje8WwTPXRgB6wk4QrXLc9sSIxm4pCTTcmCuc6a5a0rrkW5KfvQ73rZJ/L4xs6yWIp67g4vjT2xO6nMARvUoxmMi1lp083UtSnZ019q1PTHoNEbbkft+HgmAWbv+x0p0glcE48cyfjC1JEtMcCFdCnrLy292e+gwFRR8x7snSttAnAwSp22Sd2ma1uLI0ayjGWGp5vvozN+4UUPb8TsWRPZOq7p0/0aUM7D7hLsHVBcyJVZSVBJWX+KUNWLGtyqRD5AwImb24Vu137QtB2lA7cwBmaSh5+CkcYflNm9w4IvjTj/aIo123+3kYtOPyjQAb1MbumEA==;\n\t31:BIOKFHk27xTCrnEPUhfSeoXTl/0UmEOqJayZTVFKuChy4sUnLrsMANm/Gd4oqlW9O0K4dD9cb2sOCLwOD3s8fp4VCc8hVzHvND5l60BikUo15A6g0ffIyvdiFPIsXrOZXneKPYNUMU5WLWJD0EgwOMd74IHoQ7knbzdFKaCGZTGryfyRAmEzcvAJ9uVO9BlksWi8HMfhcGoBRm5bUIi7bx+3yHm4IxBi+rmUPzlk+00=",
            "1; BLUPR0701MB1652;\n\t20:walMS0XVOXE7EEBbPhZyb6oUEsnq7S/LljYbmL2Nt9NIRWHGtOgsxTEbc+Zo98hJp7jNVzgoFHhHkEp5gT0H8pA4X3ZXwjsIbKHo9y7i/MTt+AUW+RpskJozdO/sHBnlssB6hyRw0nECX8Fjt8Z9CHu2y/I5Bjg2rVOyE/cyuAmjVloeeceMs+8QgIwVxSzAW4jlnZKgsY3BC7+iH1sdYQ72Fu1JaGZSDxbqSNnSfqDULWIVwl6IxrRNJ7FMotqDTM0tooXQmPyYgdqWCM0ydIEGiQYTOwAAa70ZnODmWdERvPSagZFUeCFAbVstWwlt7N3gEJzP2GA1DOK64AT2axFyBx64z5n3AGSl5ZBy1IbNqUJHe/j+kS589tb+OIRPC4BxO4Wu/HrnXEaSOQdFz2H6KZcFMAGzFeI9b4w5+OlxBf3198meva2YuTjR9jV0+MpG+SC3rrYj2lztnMZ2yir5q99MmsBEc611mOhIywKxpFqOKHEFBUw0LsfRiK20;\n\t4:yCjZyM+Q7tj2PnAAXaSI9i/6rfryjJBQB6tbruFvvvfCbwTyBijLB9PllfmWvhgbI4HmEDMepdXIt1uyfreGdpTn4cnBIRYWCyvD4E2OS83vFEprIvXnGTsiYQyPbhfVVsOIT1LTtj1nLFZEeVr9AgAM3tFiQrxaCInkLrmzvN2vM/V3cPyNTdI4+/lNAuLM2zT7PonBmPWTn2aN1iJ7j8qgEYX9vpw8yuG3Nr+mHgFUkLJIxlhzGT5VJP0CjfPLUQmuZzyn+EO0wjJ5s4vXfg==",
            "=?us-ascii?Q?1; BLUPR0701MB1652;\n\t23:B9Ufkmqx6uVaUju9j8tYYvKmoDKP3seSUYO3tS6?=\n\tdQnGJdm+xjpUuUo0FDBob2/Rp3+EjA1JkKssvbGVa1GMqMxUVagOoeoal9AuFZSttnDJN57s3U+c8UPfdyFpYV7FwMwW/8BUyOP216zFY9zZ7bdSdx6CGG9qKaEYMgWT9yL9oxIbWnAROEgtYLToZHvZ5bXXOr3lpPbFaLs+XaXSqe2ugeV9JF9qRpJOMasujfCjoqC6a9yDzeNIxj1KwtCRtEQLVGiXEQzH1ictwaXaaKJU9PUW75ym4b+wkQBQ9W8/2hbXve23p8LbwEF3V0ncHhRz4LnSvOq5GCAvTqY0CEvZjRezHcEdbhtyM5/w00nvy36MWtwUAyNfsZxnpd1IFdWVplX8e6rXFDNa6rw/BiiG/toaQ2s4C05H/eeuriEk6U++tzebfIj9b98kUi2eBiVZSmGcat07wyVKpUW509yna1olyIrfhq1IxzeXVdoQ8/qj2bl39qomp6YOPHfrsBQTgtIOw9Pl3wWdhv8UVUmTBSHmLyZVka9gciy2X/50+IPMQmWI4b1uJQ45Kjbpz07PFKEvCL5CqV41YTDIuUSGyfohehu/3N27orCZawFJ7mtragq1SdsszndHP9pDOxfjb6t7ErG1iRkDgCdpVUSEv6dQo6Zc+hUkrG6JaDIqaK+yPVi4VAf855BrByttso1LDubSUAO29jip4NJZe+O3N3jeeYZ8Dtq/FrTHVuwiL9jbLSi3ncC37blcceEx33s4V46gXuUMZovQiBrIEb60CLKQ8qlU+Zt1cwMXYnXLLy+ZREYVJ6sq8pJzwhSJUZcX07yWVSBa9YC3048qHZO/ziEaGRvcJK3HvXdVGeWOKckHMQKhUaclMn98aKFZeK0No+IVhsb3w1G8cXDTqcedrxGjkESnTJwMIXOlAHQStR3B/in5eAoEkQP3y88Habn91VpQVI3/bPFJhmBfqY+MxCWKSkdKH3mhoraxmHzNG/YmVsFofiNC+4wj2MVjnu7X//a1We31wVDsEhMtIk/dkRJvlKoJrofY5A6oRaLl7jv0YmiMpDViF3trX9AprFJe7lCjAP6qumK/OD2fjZgF+qp1Q6jMOEwptV5P6YeMrchp3G4T7UFf/XHo0TTr7D6upDgFdKF/IQJKAxh9rxvH9MPG8FcJD5cx9OWAbKJc4BfEXmIpEUbCzXeJbnK5VbGKsHEsMaZ7K3zxBVWvOAfxT3JqJ7aS3dOn7myqRcHcl6fa6jep4PMce1ztL6lJA/CNkV1qBDlzw7+LSEa3PdEQmK0Jsqx7p6aKhX7zpN+9aWKkjTtLo28vipXPl38aBxBDR1WercyApRirzFZNtkA0AEFn16Aa/mOHwc7YebhvaJ/CY7eDs5Dj1FjkZdZFC",
            "1; BLUPR0701MB1652;\n\t6:XRNcVUbRFKFBPJQ1VsLWjWR8PeMD926XkfK0qJTZdoNP3N0ZkrOMLKFpoxbKuif5LHph6CHMWNM9NaOjeIM0mcnXa5M2LoFUNXg5v+U+ZfSZtsZ+EmDwkohgvclRst+A/Um/KjaDDoLQsWkhewG1rIlSSBwybgGjE3xgoMv++VTYL5k5di01ttuCFBEgT+bAsWNGarAehAhngeZB9j7CFUJOD+CFamfly/7HUKq6nrITGRMi46HloePf9BZSw567BUmY0lNiqeKCb5Rcri1AAntzOMLnltACZMjd+gOLHr3khodm8Imfop6toRJLAE0lDTu1Xgep18TXivQOkmABHxQvbdRaW8MTHNwCEFcTi+A85qJB8Eetm8ddUGR56J+oQN3BPgRmRfYCoiedk/pG90HqyBZQOmc0xlu4sZeUvblFSaXbGn1Nn3pOY6CkY8WEWgNfOYm0F9Yta98AuM+Icw==;\n\t5:tdm7c+w5LEdF15n7BMlp+rMcUcWCm+a7r0kVMt9SD/CrKif5yFBoMc33Wh/yOgMz8u112Ag90TsiJBArQKW4du6BdgbbfTt+EHTYZzDAQSMGGzKJKiTsj8NT5dzcLfgIhha6qOEneRjximfkPewMMSe/59UCgDYf+XBgPUv6l6w=;\n\t7:YY5kK7z6mZaReXkCXsB1PZa2a5sgJ1F0zG5vjtKjU2Q6PAvacX2RzXp1l7CIguy/E3m08+ZT7bLDMFt4ntDwNAaTLPWOAIpRmITh1hXpiuqVddYYKpXqDyaYtqa2gDKYeZSuI5CRToZkwV18s0Pq6C4blE8EB1cTFaaY3dd/zli2cRnk9WJuStwhXtr7cFCHpKaUh+c4ksmkbewwRZPcQ9p0pq0O2+R5iGz+fLSeuN6PYQ/+rXpSlLXNqzivAz5M"
        ],
        "X-MS-TrafficTypeDiagnostic": "BLUPR0701MB1652:",
        "X-Microsoft-Antispam-PRVS": "<BLUPR0701MB1652AE9EF9DC7C941AFACEAA98000@BLUPR0701MB1652.namprd07.prod.outlook.com>",
        "X-Exchange-Antispam-Report-Test": "UriScan:;",
        "X-MS-Exchange-SenderADCheck": "1",
        "X-Exchange-Antispam-Report-CFA-Test": "BCL:0; PCL:0;\n\tRULEID:(6040522)(2401047)(5005006)(8121501046)(93006095)(93001095)(3231311)(944501410)(52105095)(10201501046)(3002001)(149027)(150027)(6041310)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123558120)(20161123562045)(20161123564045)(20161123560045)(201708071742011)(7699050);\n\tSRVR:BLUPR0701MB1652; BCL:0; PCL:0; RULEID:; SRVR:BLUPR0701MB1652; ",
        "X-Forefront-PRVS": "07880C4932",
        "X-Forefront-Antispam-Report": "SFV:NSPM;\n\tSFS:(10009020)(39850400004)(396003)(376002)(366004)(346002)(136003)(189003)(199004)(81156014)(81166006)(44832011)(8936002)(2351001)(486006)(106356001)(2361001)(105586002)(446003)(2906002)(50226002)(476003)(11346002)(956004)(2616005)(305945005)(7736002)(551934003)(16586007)(316002)(54906003)(14444005)(16526019)(66066001)(26005)(7696005)(52116002)(8676002)(51416003)(76176011)(186003)(386003)(68736007)(478600001)(6666003)(6916009)(6486002)(5660300001)(53936002)(47776003)(53946003)(4326008)(25786009)(86362001)(48376002)(50466002)(575784001)(72206003)(6116002)(97736004)(36756003)(3846002)(2004002)(579004)(559001);\n\tDIR:OUT; SFP:1101; SCL:1; SRVR:BLUPR0701MB1652;\n\tH:ubuntubox.rdc.aquantia.com; \n\tFPR:; SPF:None; LANG:en; PTR:InfoNoRecords; MX:1; A:1; ",
        "Received-SPF": "None (protection.outlook.com: aquantia.com does not designate\n\tpermitted sender hosts)",
        "X-Microsoft-Antispam-Message-Info": "WJJnJl57mDE4RJz3ViTM1Fpm6EqQpz5Aw7CMBBB63o0xaiXsJZQW1JNl37P4Wy+5kGVx+/a2SKuxm9bFL5vAdwYlMCg6gSbJK+QX8qW0l9+2H8uZqxDNvjt48wnv8QJRCtWNPvcKV5LHUYhMBGxTkNEHhyafD3LZCL1idtdhTjFSDh7UBOPu15Wv3gPBhqlu1uT+5qnWqAKij60OkOXRoqY2IXeL1Pev/gS6LqzcpmlIUc0pzI89qpAVMBc4TVWOFg9ygyYm8IDd1UJgk5WQ3lFqxEbQuI63rJmr2Dh8iWM7XeP8p6u2+s1Q4dc+MpNh1IPuvalC1DS4RkSDfMCHJCrUb8idD+2ZukUEWzYRFWs=",
        "SpamDiagnosticOutput": "1:99",
        "SpamDiagnosticMetadata": "NSPM",
        "X-OriginatorOrg": "aquantia.com",
        "X-MS-Exchange-CrossTenant-OriginalArrivalTime": "07 Sep 2018 15:23:12.3479\n\t(UTC)",
        "X-MS-Exchange-CrossTenant-Network-Message-Id": "042ca868-2f8d-4c38-0808-08d614d5d401",
        "X-MS-Exchange-CrossTenant-FromEntityHeader": "Hosted",
        "X-MS-Exchange-CrossTenant-Id": "83e2e134-991c-4ede-8ced-34d47e38e6b1",
        "X-MS-Exchange-Transport-CrossTenantHeadersStamped": "BLUPR0701MB1652",
        "Subject": "[dpdk-dev] [PATCH 06/21] net/atlantic: firmware operations layer",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n\t<mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://mails.dpdk.org/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n\t<mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "AQC NICs comes in fields with two major\nFW generations: 1x and 3x.\n\nThis is part of linux atlantic driver shared code,\nresponsible for internal NIC firmware interactions,\nincluding link management ops, FW initialization,\nvarious lifecycle features.\n\nSigned-off-by: Igor Russkikh <igor.russkikh@aquantia.com>\n---\n drivers/net/atlantic/hw_atl/hw_atl_utils.c      | 942 ++++++++++++++++++++++++\n drivers/net/atlantic/hw_atl/hw_atl_utils.h      | 516 +++++++++++++\n drivers/net/atlantic/hw_atl/hw_atl_utils_fw2x.c | 623 ++++++++++++++++\n 3 files changed, 2081 insertions(+)\n create mode 100644 drivers/net/atlantic/hw_atl/hw_atl_utils.c\n create mode 100644 drivers/net/atlantic/hw_atl/hw_atl_utils.h\n create mode 100644 drivers/net/atlantic/hw_atl/hw_atl_utils_fw2x.c",
    "diff": "diff --git a/drivers/net/atlantic/hw_atl/hw_atl_utils.c b/drivers/net/atlantic/hw_atl/hw_atl_utils.c\nnew file mode 100644\nindex 000000000..c3b55baad\n--- /dev/null\n+++ b/drivers/net/atlantic/hw_atl/hw_atl_utils.c\n@@ -0,0 +1,942 @@\n+/*\n+ * aQuantia Corporation Network Driver\n+ * Copyright (C) 2014-2017 aQuantia Corporation. All rights reserved\n+ *\n+ * This program is free software; you can redistribute it and/or modify it\n+ * under the terms and conditions of the GNU General Public License,\n+ * version 2, as published by the Free Software Foundation.\n+ */\n+\n+/* File hw_atl_utils.c: Definition of common functions for Atlantic hardware\n+ * abstraction layer.\n+ */\n+\n+#include <stdio.h>\n+#include <errno.h>\n+#include <stdint.h>\n+#include <string.h>\n+#include <unistd.h>\n+#include <stdarg.h>\n+#include <inttypes.h>\n+#include <rte_ether.h>\n+#include \"../atl_hw_regs.h\"\n+\n+#include \"hw_atl_llh.h\"\n+#include \"hw_atl_llh_internal.h\"\n+#include \"../atl_logs.h\"\n+\n+#define HW_ATL_UCP_0X370_REG    0x0370U\n+\n+#define HW_ATL_MIF_CMD          0x0200U\n+#define HW_ATL_MIF_ADDR         0x0208U\n+#define HW_ATL_MIF_VAL          0x020CU\n+\n+#define HW_ATL_FW_SM_RAM        0x2U\n+#define HW_ATL_MPI_FW_VERSION\t0x18\n+#define HW_ATL_MPI_CONTROL_ADR  0x0368U\n+#define HW_ATL_MPI_STATE_ADR    0x036CU\n+\n+#define HW_ATL_MPI_STATE_MSK      0x00FFU\n+#define HW_ATL_MPI_STATE_SHIFT    0U\n+#define HW_ATL_MPI_SPEED_MSK      0x00FF0000U\n+#define HW_ATL_MPI_SPEED_SHIFT    16U\n+#define HW_ATL_MPI_DIRTY_WAKE_MSK 0x02000000U\n+\n+#define HW_ATL_MPI_DAISY_CHAIN_STATUS\t0x704\n+#define HW_ATL_MPI_BOOT_EXIT_CODE\t0x388\n+\n+#define HW_ATL_MAC_PHY_CONTROL\t0x4000\n+#define HW_ATL_MAC_PHY_MPI_RESET_BIT 0x1D\n+\n+#define HW_ATL_FW_VER_1X 0x01050006U\n+#define HW_ATL_FW_VER_2X 0x02000000U\n+#define HW_ATL_FW_VER_3X 0x03000000U\n+\n+#define FORCE_FLASHLESS 0\n+\n+static int hw_atl_utils_ver_match(u32 ver_expected, u32 ver_actual);\n+int hw_atl_utils_mpi_set_state(struct aq_hw_s *self,\n+\t\t\t\tenum hal_atl_utils_fw_state_e state);\n+\n+\n+int hw_atl_utils_initfw(struct aq_hw_s *self, const struct aq_fw_ops **fw_ops)\n+{\n+\tint err = 0;\n+\n+\terr = hw_atl_utils_soft_reset(self);\n+\tif (err)\n+\t\treturn err;\n+\n+\thw_atl_utils_hw_chip_features_init(self,\n+\t\t\t\t\t   &self->chip_features);\n+\n+\thw_atl_utils_get_fw_version(self, &self->fw_ver_actual);\n+\n+\tif (hw_atl_utils_ver_match(HW_ATL_FW_VER_1X,\n+\t\t\t\t   self->fw_ver_actual) == 0) {\n+\t\t*fw_ops = &aq_fw_1x_ops;\n+\t} else if (hw_atl_utils_ver_match(HW_ATL_FW_VER_2X,\n+\t\t\t\t\tself->fw_ver_actual) == 0) {\n+\t\t*fw_ops = &aq_fw_2x_ops;\n+\t} else if (hw_atl_utils_ver_match(HW_ATL_FW_VER_3X,\n+\t\t\t\t\tself->fw_ver_actual) == 0) {\n+\t\t*fw_ops = &aq_fw_2x_ops;\n+\t} else {\n+\t\tPMD_DRV_LOG(ERR, \"Bad FW version detected: %x\\n\",\n+\t\t\t  self->fw_ver_actual);\n+\t\treturn -EOPNOTSUPP;\n+\t}\n+\tself->aq_fw_ops = *fw_ops;\n+\terr = self->aq_fw_ops->init(self);\n+\treturn err;\n+}\n+\n+static int hw_atl_utils_soft_reset_flb(struct aq_hw_s *self)\n+{\n+\tu32 gsr, val;\n+\tint k = 0;\n+\n+\taq_hw_write_reg(self, 0x404, 0x40e1);\n+\tAQ_HW_SLEEP(50);\n+\n+\t/* Cleanup SPI */\n+\tval = aq_hw_read_reg(self, 0x53C);\n+\taq_hw_write_reg(self, 0x53C, val | 0x10);\n+\n+\tgsr = aq_hw_read_reg(self, HW_ATL_GLB_SOFT_RES_ADR);\n+\taq_hw_write_reg(self, HW_ATL_GLB_SOFT_RES_ADR, (gsr & 0xBFFF) | 0x8000);\n+\n+\t/* Kickstart MAC */\n+\taq_hw_write_reg(self, 0x404, 0x80e0);\n+\taq_hw_write_reg(self, 0x32a8, 0x0);\n+\taq_hw_write_reg(self, 0x520, 0x1);\n+\n+\t/* Reset SPI again because of possible interrupted SPI burst */\n+\tval = aq_hw_read_reg(self, 0x53C);\n+\taq_hw_write_reg(self, 0x53C, val | 0x10);\n+\tAQ_HW_SLEEP(10);\n+\t/* Clear SPI reset state */\n+\taq_hw_write_reg(self, 0x53C, val & ~0x10);\n+\n+\taq_hw_write_reg(self, 0x404, 0x180e0);\n+\n+\tfor (k = 0; k < 1000; k++) {\n+\t\tu32 flb_status = aq_hw_read_reg(self,\n+\t\t\t\t\t\tHW_ATL_MPI_DAISY_CHAIN_STATUS);\n+\n+\t\tflb_status = flb_status & 0x10;\n+\t\tif (flb_status)\n+\t\t\tbreak;\n+\t\tAQ_HW_SLEEP(10);\n+\t}\n+\tif (k == 1000) {\n+\t\tPMD_DRV_LOG(ERR, \"MAC kickstart failed\\n\");\n+\t\treturn -EIO;\n+\t}\n+\n+\t/* FW reset */\n+\taq_hw_write_reg(self, 0x404, 0x80e0);\n+\tAQ_HW_SLEEP(50);\n+\taq_hw_write_reg(self, 0x3a0, 0x1);\n+\n+\t/* Kickstart PHY - skipped */\n+\n+\t/* Global software reset*/\n+\thw_atl_rx_rx_reg_res_dis_set(self, 0U);\n+\thw_atl_tx_tx_reg_res_dis_set(self, 0U);\n+\taq_hw_write_reg_bit(self, HW_ATL_MAC_PHY_CONTROL,\n+\t\t\t    BIT(HW_ATL_MAC_PHY_MPI_RESET_BIT),\n+\t\t\t    HW_ATL_MAC_PHY_MPI_RESET_BIT, 0x0);\n+\tgsr = aq_hw_read_reg(self, HW_ATL_GLB_SOFT_RES_ADR);\n+\taq_hw_write_reg(self, HW_ATL_GLB_SOFT_RES_ADR, (gsr & 0xBFFF) | 0x8000);\n+\n+\tfor (k = 0; k < 1000; k++) {\n+\t\tu32 fw_state = aq_hw_read_reg(self, HW_ATL_MPI_FW_VERSION);\n+\n+\t\tif (fw_state)\n+\t\t\tbreak;\n+\t\tAQ_HW_SLEEP(10);\n+\t}\n+\tif (k == 1000) {\n+\t\tPMD_DRV_LOG(ERR, \"FW kickstart failed\\n\");\n+\t\treturn -EIO;\n+\t}\n+\t/* Old FW requires fixed delay after init */\n+\tAQ_HW_SLEEP(15);\n+\n+\treturn 0;\n+}\n+\n+static int hw_atl_utils_soft_reset_rbl(struct aq_hw_s *self)\n+{\n+\tu32 gsr, val, rbl_status;\n+\tint k;\n+\n+\taq_hw_write_reg(self, 0x404, 0x40e1);\n+\taq_hw_write_reg(self, 0x3a0, 0x1);\n+\taq_hw_write_reg(self, 0x32a8, 0x0);\n+\n+\t/* Alter RBL status */\n+\taq_hw_write_reg(self, 0x388, 0xDEAD);\n+\n+\t/* Cleanup SPI */\n+\tval = aq_hw_read_reg(self, 0x53C);\n+\taq_hw_write_reg(self, 0x53C, val | 0x10);\n+\n+\t/* Global software reset*/\n+\thw_atl_rx_rx_reg_res_dis_set(self, 0U);\n+\thw_atl_tx_tx_reg_res_dis_set(self, 0U);\n+\taq_hw_write_reg_bit(self, HW_ATL_MAC_PHY_CONTROL,\n+\t\t\t    BIT(HW_ATL_MAC_PHY_MPI_RESET_BIT),\n+\t\t\t    HW_ATL_MAC_PHY_MPI_RESET_BIT, 0x0);\n+\tgsr = aq_hw_read_reg(self, HW_ATL_GLB_SOFT_RES_ADR);\n+\taq_hw_write_reg(self, HW_ATL_GLB_SOFT_RES_ADR,\n+\t\t\t(gsr & 0xFFFFBFFF) | 0x8000);\n+\n+\tif (FORCE_FLASHLESS)\n+\t\taq_hw_write_reg(self, 0x534, 0x0);\n+\n+\taq_hw_write_reg(self, 0x404, 0x40e0);\n+\n+\t/* Wait for RBL boot */\n+\tfor (k = 0; k < 1000; k++) {\n+\t\trbl_status = aq_hw_read_reg(self, 0x388) & 0xFFFF;\n+\t\tif (rbl_status && rbl_status != 0xDEAD)\n+\t\t\tbreak;\n+\t\tAQ_HW_SLEEP(10);\n+\t}\n+\tif (!rbl_status || rbl_status == 0xDEAD) {\n+\t\tPMD_DRV_LOG(ERR, \"RBL Restart failed\");\n+\t\treturn -EIO;\n+\t}\n+\n+\t/* Restore NVR */\n+\tif (FORCE_FLASHLESS)\n+\t\taq_hw_write_reg(self, 0x534, 0xA0);\n+\n+\tif (rbl_status == 0xF1A7) {\n+\t\tPMD_DRV_LOG(ERR, \"No FW detected. Dynamic FW load not implemented\\n\");\n+\t\treturn -EOPNOTSUPP;\n+\t}\n+\n+\tfor (k = 0; k < 1000; k++) {\n+\t\tu32 fw_state = aq_hw_read_reg(self, HW_ATL_MPI_FW_VERSION);\n+\n+\t\tif (fw_state)\n+\t\t\tbreak;\n+\t\tAQ_HW_SLEEP(10);\n+\t}\n+\tif (k == 1000) {\n+\t\tPMD_DRV_LOG(ERR, \"FW kickstart failed\\n\");\n+\t\treturn -EIO;\n+\t}\n+\t/* Old FW requires fixed delay after init */\n+\tAQ_HW_SLEEP(15);\n+\n+\treturn 0;\n+}\n+\n+int hw_atl_utils_soft_reset(struct aq_hw_s *self)\n+{\n+\tint err = 0;\n+\tint k;\n+\tu32 boot_exit_code = 0;\n+\n+\tfor (k = 0; k < 1000; ++k) {\n+\t\tu32 flb_status = aq_hw_read_reg(self,\n+\t\t\t\t\t\tHW_ATL_MPI_DAISY_CHAIN_STATUS);\n+\t\tboot_exit_code = aq_hw_read_reg(self,\n+\t\t\t\t\t\tHW_ATL_MPI_BOOT_EXIT_CODE);\n+\t\tif (flb_status != 0x06000000 || boot_exit_code != 0)\n+\t\t\tbreak;\n+\t}\n+\n+\tif (k == 1000) {\n+\t\tPMD_DRV_LOG(ERR, \"Neither RBL nor FLB firmware started\\n\");\n+\t\treturn -EOPNOTSUPP;\n+\t}\n+\n+\tself->rbl_enabled = (boot_exit_code != 0);\n+\n+\t/* FW 1.x may bootup in an invalid POWER state (WOL feature).\n+\t * We should work around this by forcing its state back to DEINIT\n+\t */\n+\tif (!hw_atl_utils_ver_match(HW_ATL_FW_VER_1X,\n+\t\t\t\t    aq_hw_read_reg(self,\n+\t\t\t\t\t\t   HW_ATL_MPI_FW_VERSION))) {\n+\t\thw_atl_utils_mpi_set_state(self, MPI_DEINIT);\n+\t\tAQ_HW_WAIT_FOR((aq_hw_read_reg(self, HW_ATL_MPI_STATE_ADR) &\n+\t\t\t       HW_ATL_MPI_STATE_MSK) == MPI_DEINIT,\n+\t\t\t       10, 1000U);\n+\t}\n+\n+\tif (self->rbl_enabled)\n+\t\terr = hw_atl_utils_soft_reset_rbl(self);\n+\telse\n+\t\terr = hw_atl_utils_soft_reset_flb(self);\n+\n+\treturn err;\n+}\n+\n+int hw_atl_utils_fw_downld_dwords(struct aq_hw_s *self, u32 a,\n+\t\t\t\t  u32 *p, u32 cnt)\n+{\n+\tint err = 0;\n+\n+\tAQ_HW_WAIT_FOR(hw_atl_reg_glb_cpu_sem_get(self,\n+\t\t\t\t\t\t  HW_ATL_FW_SM_RAM) == 1U,\n+\t\t\t\t\t\t  1U, 10000U);\n+\n+\tif (err < 0) {\n+\t\tbool is_locked;\n+\n+\t\thw_atl_reg_glb_cpu_sem_set(self, 1U, HW_ATL_FW_SM_RAM);\n+\t\tis_locked = hw_atl_reg_glb_cpu_sem_get(self, HW_ATL_FW_SM_RAM);\n+\t\tif (!is_locked) {\n+\t\t\terr = -ETIME;\n+\t\t\tgoto err_exit;\n+\t\t}\n+\t}\n+\n+\taq_hw_write_reg(self, HW_ATL_MIF_ADDR, a);\n+\n+\tfor (++cnt; --cnt && !err;) {\n+\t\taq_hw_write_reg(self, HW_ATL_MIF_CMD, 0x00008000U);\n+\n+\t\tif (IS_CHIP_FEATURE(REVISION_B1))\n+\t\t\tAQ_HW_WAIT_FOR(a != aq_hw_read_reg(self,\n+\t\t\t\t\t\t\t   HW_ATL_MIF_ADDR),\n+\t\t\t\t       1, 1000U);\n+\t\telse\n+\t\t\tAQ_HW_WAIT_FOR(!(0x100 & aq_hw_read_reg(self,\n+\t\t\t\t\t\t\t   HW_ATL_MIF_CMD)),\n+\t\t\t\t       1, 1000U);\n+\n+\t\t*(p++) = aq_hw_read_reg(self, HW_ATL_MIF_VAL);\n+\t\ta += 4;\n+\t}\n+\n+\thw_atl_reg_glb_cpu_sem_set(self, 1U, HW_ATL_FW_SM_RAM);\n+\n+err_exit:\n+\treturn err;\n+}\n+\n+int hw_atl_utils_fw_upload_dwords(struct aq_hw_s *self, u32 a, u32 *p,\n+\t\t\t\t\t u32 cnt)\n+{\n+\tint err = 0;\n+\tbool is_locked;\n+\n+\tis_locked = hw_atl_reg_glb_cpu_sem_get(self, HW_ATL_FW_SM_RAM);\n+\tif (!is_locked) {\n+\t\terr = -ETIME;\n+\t\tgoto err_exit;\n+\t}\n+\tif (IS_CHIP_FEATURE(REVISION_B1)) {\n+\t\tu32 offset = 0;\n+\n+\t\tfor (; offset < cnt; ++offset) {\n+\t\t\taq_hw_write_reg(self, 0x328, p[offset]);\n+\t\t\taq_hw_write_reg(self, 0x32C,\n+\t\t\t\t(0x80000000 | (0xFFFF & (offset * 4))));\n+\t\t\tmcp_up_force_intr_set(self, 1);\n+\t\t\t/* 1000 times by 10us = 10ms */\n+\t\t\tAQ_HW_WAIT_FOR((aq_hw_read_reg(self,\n+\t\t\t\t\t0x32C) & 0xF0000000) != 0x80000000,\n+\t\t\t\t\t10, 1000);\n+\t\t}\n+\t} else {\n+\t\tu32 offset = 0;\n+\n+\t\taq_hw_write_reg(self, 0x208, a);\n+\n+\t\tfor (; offset < cnt; ++offset) {\n+\t\t\taq_hw_write_reg(self, 0x20C, p[offset]);\n+\t\t\taq_hw_write_reg(self, 0x200, 0xC000);\n+\n+\t\t\tAQ_HW_WAIT_FOR((aq_hw_read_reg(self, 0x200U)\n+\t\t\t\t\t& 0x100) == 0, 10, 1000);\n+\t\t}\n+\t}\n+\n+\thw_atl_reg_glb_cpu_sem_set(self, 1U, HW_ATL_FW_SM_RAM);\n+\n+err_exit:\n+\treturn err;\n+}\n+\n+static int hw_atl_utils_ver_match(u32 ver_expected, u32 ver_actual)\n+{\n+\tint err = 0;\n+\tconst u32 dw_major_mask = 0xff000000U;\n+\tconst u32 dw_minor_mask = 0x00ffffffU;\n+\n+\terr = (dw_major_mask & (ver_expected ^ ver_actual)) ? -EOPNOTSUPP : 0;\n+\tif (err < 0)\n+\t\tgoto err_exit;\n+\terr = ((dw_minor_mask & ver_expected) > (dw_minor_mask & ver_actual)) ?\n+\t\t-EOPNOTSUPP : 0;\n+err_exit:\n+\treturn err;\n+}\n+\n+static int hw_atl_utils_init_ucp(struct aq_hw_s *self)\n+{\n+\tint err = 0;\n+\n+\tif (!aq_hw_read_reg(self, 0x370U)) {\n+\t\tunsigned int rnd = (uint32_t)rte_rand();\n+\t\tunsigned int ucp_0x370 = 0U;\n+\n+\t\tucp_0x370 = 0x02020202U | (0xFEFEFEFEU & rnd);\n+\t\taq_hw_write_reg(self, HW_ATL_UCP_0X370_REG, ucp_0x370);\n+\t}\n+\n+\thw_atl_reg_glb_cpu_scratch_scp_set(self, 0x00000000U, 25U);\n+\n+\t/* check 10 times by 1ms */\n+\tAQ_HW_WAIT_FOR(0U != (self->mbox_addr =\n+\t\t       aq_hw_read_reg(self, 0x360U)), 1000U, 10U);\n+\tAQ_HW_WAIT_FOR(0U != (self->rpc_addr =\n+\t\t       aq_hw_read_reg(self, 0x334U)), 1000U, 100U);\n+\n+\treturn err;\n+}\n+\n+#define HW_ATL_RPC_CONTROL_ADR 0x0338U\n+#define HW_ATL_RPC_STATE_ADR   0x033CU\n+\n+struct aq_hw_atl_utils_fw_rpc_tid_s {\n+\tunion {\n+\t\tu32 val;\n+\t\tstruct {\n+\t\t\tu16 tid;\n+\t\t\tu16 len;\n+\t\t};\n+\t};\n+};\n+\n+#define hw_atl_utils_fw_rpc_init(_H_) hw_atl_utils_fw_rpc_wait(_H_, NULL)\n+\n+int hw_atl_utils_fw_rpc_call(struct aq_hw_s *self, unsigned int rpc_size)\n+{\n+\tint err = 0;\n+\tstruct aq_hw_atl_utils_fw_rpc_tid_s sw;\n+\n+\tif (!IS_CHIP_FEATURE(MIPS)) {\n+\t\terr = -1;\n+\t\tgoto err_exit;\n+\t}\n+\terr = hw_atl_utils_fw_upload_dwords(self, self->rpc_addr,\n+\t\t\t\t\t    (u32 *)(void *)&self->rpc,\n+\t\t\t\t\t    (rpc_size + sizeof(u32) -\n+\t\t\t\t\t    sizeof(u8)) / sizeof(u32));\n+\tif (err < 0)\n+\t\tgoto err_exit;\n+\n+\tsw.tid = 0xFFFFU & (++self->rpc_tid);\n+\tsw.len = (u16)rpc_size;\n+\taq_hw_write_reg(self, HW_ATL_RPC_CONTROL_ADR, sw.val);\n+\n+err_exit:\n+\treturn err;\n+}\n+\n+int hw_atl_utils_fw_rpc_wait(struct aq_hw_s *self,\n+\t\t\t\t    struct hw_aq_atl_utils_fw_rpc **rpc)\n+{\n+\tint err = 0;\n+\tstruct aq_hw_atl_utils_fw_rpc_tid_s sw;\n+\tstruct aq_hw_atl_utils_fw_rpc_tid_s fw;\n+\n+\tdo {\n+\t\tsw.val = aq_hw_read_reg(self, HW_ATL_RPC_CONTROL_ADR);\n+\n+\t\tself->rpc_tid = sw.tid;\n+\n+\t\tAQ_HW_WAIT_FOR(sw.tid ==\n+\t\t\t\t(fw.val =\n+\t\t\t\taq_hw_read_reg(self, HW_ATL_RPC_STATE_ADR),\n+\t\t\t\tfw.tid), 1000U, 100U);\n+\t\tif (err < 0)\n+\t\t\tgoto err_exit;\n+\n+\t\tif (fw.len == 0xFFFFU) {\n+\t\t\terr = hw_atl_utils_fw_rpc_call(self, sw.len);\n+\t\t\tif (err < 0)\n+\t\t\t\tgoto err_exit;\n+\t\t}\n+\t} while (sw.tid != fw.tid || 0xFFFFU == fw.len);\n+\tif (err < 0)\n+\t\tgoto err_exit;\n+\n+\tif (rpc) {\n+\t\tif (fw.len) {\n+\t\t\terr =\n+\t\t\thw_atl_utils_fw_downld_dwords(self,\n+\t\t\t\t\t\t      self->rpc_addr,\n+\t\t\t\t\t\t      (u32 *)(void *)\n+\t\t\t\t\t\t      &self->rpc,\n+\t\t\t\t\t\t      (fw.len + sizeof(u32) -\n+\t\t\t\t\t\t      sizeof(u8)) /\n+\t\t\t\t\t\t      sizeof(u32));\n+\t\t\tif (err < 0)\n+\t\t\t\tgoto err_exit;\n+\t\t}\n+\n+\t\t*rpc = &self->rpc;\n+\t}\n+\n+err_exit:\n+\treturn err;\n+}\n+\n+static int hw_atl_utils_mpi_create(struct aq_hw_s *self)\n+{\n+\tint err = 0;\n+\n+\terr = hw_atl_utils_init_ucp(self);\n+\tif (err < 0)\n+\t\tgoto err_exit;\n+\n+\terr = hw_atl_utils_fw_rpc_init(self);\n+\tif (err < 0)\n+\t\tgoto err_exit;\n+\n+err_exit:\n+\treturn err;\n+}\n+\n+int hw_atl_utils_mpi_read_mbox(struct aq_hw_s *self,\n+\t\t\t       struct hw_aq_atl_utils_mbox_header *pmbox)\n+{\n+\treturn hw_atl_utils_fw_downld_dwords(self,\n+\t\t\t\t      self->mbox_addr,\n+\t\t\t\t      (u32 *)(void *)pmbox,\n+\t\t\t\t      sizeof(*pmbox) / sizeof(u32));\n+}\n+\n+void hw_atl_utils_mpi_read_stats(struct aq_hw_s *self,\n+\t\t\t\t struct hw_aq_atl_utils_mbox *pmbox)\n+{\n+\tint err = 0;\n+\n+\terr = hw_atl_utils_fw_downld_dwords(self,\n+\t\t\t\t\t    self->mbox_addr,\n+\t\t\t\t\t    (u32 *)(void *)pmbox,\n+\t\t\t\t\t    sizeof(*pmbox) / sizeof(u32));\n+\tif (err < 0)\n+\t\tgoto err_exit;\n+\n+\tif (IS_CHIP_FEATURE(REVISION_A0)) {\n+\t\tunsigned int mtu = 1514; //TODO self->aq_nic_cfg ? self->aq_nic_cfg->mtu : 1514U;\n+\t\tpmbox->stats.ubrc = pmbox->stats.uprc * mtu;\n+\t\tpmbox->stats.ubtc = pmbox->stats.uptc * mtu;\n+\t\t//TODO pmbox->stats.dpc = atomic_read(&self->dpc);\n+\t} else {\n+\t\tpmbox->stats.dpc = hw_atl_rpb_rx_dma_drop_pkt_cnt_get(self);\n+\t}\n+\n+err_exit:;\n+}\n+\n+static\n+int hw_atl_utils_mpi_set_speed(struct aq_hw_s *self, u32 speed)\n+{\n+\tu32 val = aq_hw_read_reg(self, HW_ATL_MPI_CONTROL_ADR);\n+\n+\tval = val & ~HW_ATL_MPI_SPEED_MSK;\n+\tval |= speed << HW_ATL_MPI_SPEED_SHIFT;\n+\taq_hw_write_reg(self, HW_ATL_MPI_CONTROL_ADR, val);\n+\n+\treturn 0;\n+}\n+\n+int hw_atl_utils_mpi_set_state(struct aq_hw_s *self,\n+\t\t\t\tenum hal_atl_utils_fw_state_e state)\n+{\n+\tint err = 0;\n+\tu32 transaction_id = 0;\n+\tstruct hw_aq_atl_utils_mbox_header mbox;\n+\tu32 val = aq_hw_read_reg(self, HW_ATL_MPI_CONTROL_ADR);\n+\n+\tif (state == MPI_RESET) {\n+\t\thw_atl_utils_mpi_read_mbox(self, &mbox);\n+\n+\t\ttransaction_id = mbox.transaction_id;\n+\n+\t\tAQ_HW_WAIT_FOR(transaction_id !=\n+\t\t\t\t(hw_atl_utils_mpi_read_mbox(self, &mbox),\n+\t\t\t\t mbox.transaction_id),\n+\t\t\t       1000U, 100U);\n+\t\tif (err < 0)\n+\t\t\tgoto err_exit;\n+\t}\n+\t/* On interface DEINIT we disable DW (raise bit)\n+\t * Otherwise enable DW (clear bit)\n+\t */\n+\tif (state == MPI_DEINIT || state == MPI_POWER)\n+\t\tval |= HW_ATL_MPI_DIRTY_WAKE_MSK;\n+\telse\n+\t\tval &= ~HW_ATL_MPI_DIRTY_WAKE_MSK;\n+\n+\t/* Set new state bits */\n+\tval = val & ~HW_ATL_MPI_STATE_MSK;\n+\tval |= state & HW_ATL_MPI_STATE_MSK;\n+\n+\taq_hw_write_reg(self, HW_ATL_MPI_CONTROL_ADR, val);\n+err_exit:\n+\treturn err;\n+}\n+\n+int hw_atl_utils_mpi_get_link_status(struct aq_hw_s *self)\n+{\n+\tu32 cp0x036C = aq_hw_read_reg(self, HW_ATL_MPI_STATE_ADR);\n+\tu32 link_speed_mask = cp0x036C >> HW_ATL_MPI_SPEED_SHIFT;\n+\tstruct aq_hw_link_status_s *link_status = &self->aq_link_status;\n+\n+\tif (!link_speed_mask) {\n+\t\tlink_status->mbps = 0U;\n+\t} else {\n+\t\tswitch (link_speed_mask) {\n+\t\tcase HAL_ATLANTIC_RATE_10G:\n+\t\t\tlink_status->mbps = 10000U;\n+\t\t\tbreak;\n+\n+\t\tcase HAL_ATLANTIC_RATE_5G:\n+\t\tcase HAL_ATLANTIC_RATE_5GSR:\n+\t\t\tlink_status->mbps = 5000U;\n+\t\t\tbreak;\n+\n+\t\tcase HAL_ATLANTIC_RATE_2GS:\n+\t\t\tlink_status->mbps = 2500U;\n+\t\t\tbreak;\n+\n+\t\tcase HAL_ATLANTIC_RATE_1G:\n+\t\t\tlink_status->mbps = 1000U;\n+\t\t\tbreak;\n+\n+\t\tcase HAL_ATLANTIC_RATE_100M:\n+\t\t\tlink_status->mbps = 100U;\n+\t\t\tbreak;\n+\n+\t\tdefault:\n+\t\t\treturn -EBUSY;\n+\t\t}\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int hw_atl_utils_get_mac_permanent(struct aq_hw_s *self,\n+\t\t\t\t   u8 *mac)\n+{\n+\tint err = 0;\n+\tu32 h = 0U;\n+\tu32 l = 0U;\n+\tu32 mac_addr[2];\n+\n+\tif (!aq_hw_read_reg(self, HW_ATL_UCP_0X370_REG)) {\n+\t\tunsigned int rnd = (uint32_t)rte_rand();\n+\t\tunsigned int ucp_0x370 = 0;\n+\n+\t\t//get_random_bytes(&rnd, sizeof(unsigned int));\n+\n+\t\tucp_0x370 = 0x02020202 | (0xFEFEFEFE & rnd);\n+\t\taq_hw_write_reg(self, HW_ATL_UCP_0X370_REG, ucp_0x370);\n+\t}\n+\n+\terr = hw_atl_utils_fw_downld_dwords(self,\n+\t\t\t\t\t    aq_hw_read_reg(self, 0x00000374U) +\n+\t\t\t\t\t    (40U * 4U),\n+\t\t\t\t\t    mac_addr,\n+\t\t\t\t\t    ARRAY_SIZE(mac_addr));\n+\tif (err < 0) {\n+\t\tmac_addr[0] = 0U;\n+\t\tmac_addr[1] = 0U;\n+\t\terr = 0;\n+\t} else {\n+\t\tmac_addr[0] = rte_constant_bswap32(mac_addr[0]);\n+\t\tmac_addr[1] = rte_constant_bswap32(mac_addr[1]);\n+\t}\n+\n+\tether_addr_copy((struct ether_addr *)mac_addr, (struct ether_addr *)mac);\n+\n+\tif ((mac[0] & 0x01U) || ((mac[0] | mac[1] | mac[2]) == 0x00U)) {\n+\t\t/* chip revision */\n+\t\tl = 0xE3000000U\n+\t\t\t| (0xFFFFU & aq_hw_read_reg(self, HW_ATL_UCP_0X370_REG))\n+\t\t\t| (0x00 << 16);\n+\t\th = 0x8001300EU;\n+\n+\t\tmac[5] = (u8)(0xFFU & l);\n+\t\tl >>= 8;\n+\t\tmac[4] = (u8)(0xFFU & l);\n+\t\tl >>= 8;\n+\t\tmac[3] = (u8)(0xFFU & l);\n+\t\tl >>= 8;\n+\t\tmac[2] = (u8)(0xFFU & l);\n+\t\tmac[1] = (u8)(0xFFU & h);\n+\t\th >>= 8;\n+\t\tmac[0] = (u8)(0xFFU & h);\n+\t}\n+\n+\treturn err;\n+}\n+\n+unsigned int hw_atl_utils_mbps_2_speed_index(unsigned int mbps)\n+{\n+\tunsigned int ret = 0U;\n+\n+\tswitch (mbps) {\n+\tcase 100U:\n+\t\tret = 5U;\n+\t\tbreak;\n+\n+\tcase 1000U:\n+\t\tret = 4U;\n+\t\tbreak;\n+\n+\tcase 2500U:\n+\t\tret = 3U;\n+\t\tbreak;\n+\n+\tcase 5000U:\n+\t\tret = 1U;\n+\t\tbreak;\n+\n+\tcase 10000U:\n+\t\tret = 0U;\n+\t\tbreak;\n+\n+\tdefault:\n+\t\tbreak;\n+\t}\n+\treturn ret;\n+}\n+\n+void hw_atl_utils_hw_chip_features_init(struct aq_hw_s *self, u32 *p)\n+{\n+\tu32 chip_features = 0U;\n+\tu32 val = hw_atl_reg_glb_mif_id_get(self);\n+\tu32 mif_rev = val & 0xFFU;\n+\n+\tif ((0xFU & mif_rev) == 1U) {\n+\t\tchip_features |= HAL_ATLANTIC_UTILS_CHIP_REVISION_A0 |\n+\t\t\tHAL_ATLANTIC_UTILS_CHIP_MPI_AQ |\n+\t\t\tHAL_ATLANTIC_UTILS_CHIP_MIPS;\n+\t} else if ((0xFU & mif_rev) == 2U) {\n+\t\tchip_features |= HAL_ATLANTIC_UTILS_CHIP_REVISION_B0 |\n+\t\t\tHAL_ATLANTIC_UTILS_CHIP_MPI_AQ |\n+\t\t\tHAL_ATLANTIC_UTILS_CHIP_MIPS |\n+\t\t\tHAL_ATLANTIC_UTILS_CHIP_TPO2 |\n+\t\t\tHAL_ATLANTIC_UTILS_CHIP_RPF2;\n+\t} else if ((0xFU & mif_rev) == 0xAU) {\n+\t\tchip_features |= HAL_ATLANTIC_UTILS_CHIP_REVISION_B1 |\n+\t\t\tHAL_ATLANTIC_UTILS_CHIP_MPI_AQ |\n+\t\t\tHAL_ATLANTIC_UTILS_CHIP_MIPS |\n+\t\t\tHAL_ATLANTIC_UTILS_CHIP_TPO2 |\n+\t\t\tHAL_ATLANTIC_UTILS_CHIP_RPF2;\n+\t}\n+\n+\t*p = chip_features;\n+}\n+\n+static int hw_atl_fw1x_deinit(struct aq_hw_s *self)\n+{\n+\thw_atl_utils_mpi_set_speed(self, 0);\n+\thw_atl_utils_mpi_set_state(self, MPI_DEINIT);\n+\treturn 0;\n+}\n+\n+int hw_atl_utils_update_stats(struct aq_hw_s *self)\n+{\n+\tstruct hw_aq_atl_utils_mbox mbox;\n+\n+\thw_atl_utils_mpi_read_stats(self, &mbox);\n+\n+#define AQ_SDELTA(_N_) (self->curr_stats._N_ += \\\n+\t\t\tmbox.stats._N_ - self->last_stats._N_)\n+\n+\tif (1) {//self->aq_link_status.mbps) {\n+\t\tAQ_SDELTA(uprc);\n+\t\tAQ_SDELTA(mprc);\n+\t\tAQ_SDELTA(bprc);\n+\t\tAQ_SDELTA(erpt);\n+\n+\t\tAQ_SDELTA(uptc);\n+\t\tAQ_SDELTA(mptc);\n+\t\tAQ_SDELTA(bptc);\n+\t\tAQ_SDELTA(erpr);\n+\t\tAQ_SDELTA(ubrc);\n+\t\tAQ_SDELTA(ubtc);\n+\t\tAQ_SDELTA(mbrc);\n+\t\tAQ_SDELTA(mbtc);\n+\t\tAQ_SDELTA(bbrc);\n+\t\tAQ_SDELTA(bbtc);\n+\t\tAQ_SDELTA(dpc);\n+\t}\n+#undef AQ_SDELTA\n+\tself->curr_stats.dma_pkt_rc = hw_atl_stats_rx_dma_good_pkt_counterlsw_get(self) +\n+\t\t\t((u64)hw_atl_stats_rx_dma_good_pkt_countermsw_get(self) << 32);\n+\tself->curr_stats.dma_pkt_tc = hw_atl_stats_tx_dma_good_pkt_counterlsw_get(self) +\n+\t\t\t((u64)hw_atl_stats_tx_dma_good_pkt_countermsw_get(self) << 32);\n+\tself->curr_stats.dma_oct_rc = hw_atl_stats_rx_dma_good_octet_counterlsw_get(self) +\n+\t\t\t((u64)hw_atl_stats_rx_dma_good_octet_countermsw_get(self) << 32);\n+\tself->curr_stats.dma_oct_tc = hw_atl_stats_tx_dma_good_octet_counterlsw_get(self) +\n+\t\t\t((u64)hw_atl_stats_tx_dma_good_octet_countermsw_get(self) << 32);\n+\n+\tself->curr_stats.dpc = hw_atl_rpb_rx_dma_drop_pkt_cnt_get(self);\n+\n+\tmemcpy(&self->last_stats, &mbox.stats, sizeof(mbox.stats));\n+\n+\treturn 0;\n+}\n+\n+struct aq_stats_s *hw_atl_utils_get_hw_stats(struct aq_hw_s *self)\n+{\n+\treturn &self->curr_stats;\n+}\n+\n+static const u32 hw_atl_utils_hw_mac_regs[] = {\n+\t0x00005580U, 0x00005590U, 0x000055B0U, 0x000055B4U,\n+\t0x000055C0U, 0x00005B00U, 0x00005B04U, 0x00005B08U,\n+\t0x00005B0CU, 0x00005B10U, 0x00005B14U, 0x00005B18U,\n+\t0x00005B1CU, 0x00005B20U, 0x00005B24U, 0x00005B28U,\n+\t0x00005B2CU, 0x00005B30U, 0x00005B34U, 0x00005B38U,\n+\t0x00005B3CU, 0x00005B40U, 0x00005B44U, 0x00005B48U,\n+\t0x00005B4CU, 0x00005B50U, 0x00005B54U, 0x00005B58U,\n+\t0x00005B5CU, 0x00005B60U, 0x00005B64U, 0x00005B68U,\n+\t0x00005B6CU, 0x00005B70U, 0x00005B74U, 0x00005B78U,\n+\t0x00005B7CU, 0x00007C00U, 0x00007C04U, 0x00007C08U,\n+\t0x00007C0CU, 0x00007C10U, 0x00007C14U, 0x00007C18U,\n+\t0x00007C1CU, 0x00007C20U, 0x00007C40U, 0x00007C44U,\n+\t0x00007C48U, 0x00007C4CU, 0x00007C50U, 0x00007C54U,\n+\t0x00007C58U, 0x00007C5CU, 0x00007C60U, 0x00007C80U,\n+\t0x00007C84U, 0x00007C88U, 0x00007C8CU, 0x00007C90U,\n+\t0x00007C94U, 0x00007C98U, 0x00007C9CU, 0x00007CA0U,\n+\t0x00007CC0U, 0x00007CC4U, 0x00007CC8U, 0x00007CCCU,\n+\t0x00007CD0U, 0x00007CD4U, 0x00007CD8U, 0x00007CDCU,\n+\t0x00007CE0U, 0x00000300U, 0x00000304U, 0x00000308U,\n+\t0x0000030cU, 0x00000310U, 0x00000314U, 0x00000318U,\n+\t0x0000031cU, 0x00000360U, 0x00000364U, 0x00000368U,\n+\t0x0000036cU, 0x00000370U, 0x00000374U, 0x00006900U,\n+};\n+\n+unsigned int hw_atl_utils_hw_get_reg_length(void)\n+{\n+\treturn ARRAY_SIZE(hw_atl_utils_hw_mac_regs);\n+}\n+\n+int hw_atl_utils_hw_get_regs(struct aq_hw_s *self,\n+\t\t\t     u32 *regs_buff)\n+{\n+\tunsigned int i = 0U;\n+\tunsigned int mac_regs_count = hw_atl_utils_hw_get_reg_length();\n+\n+\tfor (i = 0; i < mac_regs_count; i++)\n+\t\tregs_buff[i] = aq_hw_read_reg(self,\n+\t\t\t\t\t      hw_atl_utils_hw_mac_regs[i]);\n+\treturn 0;\n+}\n+\n+int hw_atl_utils_get_fw_version(struct aq_hw_s *self, u32 *fw_version)\n+{\n+\t*fw_version = aq_hw_read_reg(self, 0x18U);\n+\treturn 0;\n+}\n+\n+static int aq_fw1x_set_wol(struct aq_hw_s *self, bool wol_enabled, u8 *mac)\n+{\n+\tstruct hw_aq_atl_utils_fw_rpc *prpc = NULL;\n+\tunsigned int rpc_size = 0U;\n+\tint err = 0;\n+\n+\terr = hw_atl_utils_fw_rpc_wait(self, &prpc);\n+\tif (err < 0)\n+\t\t\t\tgoto err_exit;\n+\n+\tmemset(prpc, 0, sizeof *prpc);\n+\n+\tif (wol_enabled) {\n+\t\trpc_size = sizeof(prpc->msg_id) + sizeof(prpc->msg_wol);\n+\n+\t\tprpc->msg_id = HAL_ATLANTIC_UTILS_FW_MSG_WOL_ADD;\n+\t\tprpc->msg_wol.priority = 0x10000000; /* normal priority */\n+\t\tprpc->msg_wol.pattern_id = 1U;\n+\t\tprpc->msg_wol.wol_packet_type = 2U; /* Magic Packet */\n+\n+\t\tether_addr_copy((struct ether_addr *)mac, (struct ether_addr *)&prpc->msg_wol.wol_pattern);\n+\t} else {\n+\t\trpc_size = sizeof(prpc->msg_id) + sizeof(prpc->msg_del_id);\n+\n+\t\tprpc->msg_id = HAL_ATLANTIC_UTILS_FW_MSG_WOL_DEL;\n+\t\tprpc->msg_wol.pattern_id = 1U;\n+\t}\n+\n+\terr = hw_atl_utils_fw_rpc_call(self, rpc_size);\n+\tif (err < 0)\n+\t\tgoto err_exit;\n+err_exit:\n+\treturn err;\n+}\n+\n+static\n+int aq_fw1x_set_power(struct aq_hw_s *self, unsigned int power_state __rte_unused,\n+\t\tu8 *mac)\n+{\n+\tstruct hw_aq_atl_utils_fw_rpc *prpc = NULL;\n+\tunsigned int rpc_size = 0U;\n+\tint err = 0;\n+\tif (self->aq_nic_cfg->wol & AQ_NIC_WOL_ENABLED) {\n+\t\terr = aq_fw1x_set_wol(self, 1, mac);\n+\n+\t\tif (err < 0)\n+\t\t\tgoto err_exit;\n+\n+\t\trpc_size = sizeof(prpc->msg_id) +\n+\t\t\t\tsizeof(prpc->msg_enable_wakeup);\n+\n+\t\terr = hw_atl_utils_fw_rpc_wait(self, &prpc);\n+\n+\t\tif (err < 0)\n+\t\t\tgoto err_exit;\n+\n+\t\tmemset(prpc, 0, rpc_size);\n+\n+\t\tprpc->msg_id = HAL_ATLANTIC_UTILS_FW_MSG_ENABLE_WAKEUP;\n+\t\tprpc->msg_enable_wakeup.pattern_mask = 0x00000002;\n+\n+\t\terr = hw_atl_utils_fw_rpc_call(self, rpc_size);\n+\t\tif (err < 0)\n+\t\t\tgoto err_exit;\n+\t}\n+\n+\thw_atl_utils_mpi_set_speed(self, 0);\n+\thw_atl_utils_mpi_set_state(self, MPI_POWER);\n+err_exit:\n+\treturn err;\n+}\n+\n+\n+\n+const struct aq_fw_ops aq_fw_1x_ops = {\n+\t.init = hw_atl_utils_mpi_create,\n+\t.deinit = hw_atl_fw1x_deinit,\n+\t.reset = NULL,\n+\t.get_mac_permanent = hw_atl_utils_get_mac_permanent,\n+\t.set_link_speed = hw_atl_utils_mpi_set_speed,\n+\t.set_state = hw_atl_utils_mpi_set_state,\n+\t.update_link_status = hw_atl_utils_mpi_get_link_status,\n+\t.update_stats = hw_atl_utils_update_stats,\n+\t.set_power = aq_fw1x_set_power,\n+\t.get_temp = NULL,\n+\t.get_cable_len = NULL,\n+\t.set_eee_rate = NULL,\n+\t.get_eee_rate = NULL,\n+\t.set_flow_control = NULL,\n+\t.led_control = NULL,\n+\t.get_eeprom = NULL,\n+\t.set_eeprom = NULL,\n+};\ndiff --git a/drivers/net/atlantic/hw_atl/hw_atl_utils.h b/drivers/net/atlantic/hw_atl/hw_atl_utils.h\nnew file mode 100644\nindex 000000000..5df0e1c26\n--- /dev/null\n+++ b/drivers/net/atlantic/hw_atl/hw_atl_utils.h\n@@ -0,0 +1,516 @@\n+/*\n+ * aQuantia Corporation Network Driver\n+ * Copyright (C) 2014-2017 aQuantia Corporation. All rights reserved\n+ *\n+ * This program is free software; you can redistribute it and/or modify it\n+ * under the terms and conditions of the GNU General Public License,\n+ * version 2, as published by the Free Software Foundation.\n+ */\n+\n+/* File hw_atl_utils.h: Declaration of common functions for Atlantic hardware\n+ * abstraction layer.\n+ */\n+\n+#ifndef HW_ATL_UTILS_H\n+#define HW_ATL_UTILS_H\n+\n+#define HW_ATL_FLUSH() { (void)aq_hw_read_reg(self, 0x10); }\n+\n+/* Hardware tx descriptor */\n+struct hw_atl_txd_s {\n+    u64 buf_addr;\n+        \n+    union {\n+        struct {\n+            u32 type:3;\n+            u32 :1;\n+            u32 len:16;\n+            u32 dd:1;\n+            u32 eop:1;\n+            u32 cmd:8;\n+            u32 :14;\n+            u32 ct_idx:1;\n+            u32 ct_en:1;\n+            u32 pay_len:18;\n+        } __attribute__((__packed__));\n+        u64 flags;        \n+    };\n+} __attribute__((__packed__));\n+\n+/* Hardware tx context descriptor */\n+union hw_atl_txc_s {\n+    struct {\n+        u64 flags1;\n+        u64 flags2;\n+    };\n+    \n+    struct {\n+        u64 :40;\n+        u32 tun_len:8;\n+        u32 out_len:16;\n+        u32 type:3;\n+        u32 idx:1;\n+        u32 vlan_tag:16;\n+        u32 cmd:4;\n+        u32 l2_len:7;\n+        u32 l3_len:9;\n+        u32 l4_len:8;\n+        u32 mss_len:16;\n+    } __attribute__((__packed__));\n+} __attribute__((__packed__));\n+\n+enum aq_tx_desc_type {\n+    tx_desc_type_desc = 1,\n+    tx_desc_type_ctx = 2,\n+};\n+\n+enum aq_tx_desc_cmd {\n+    tx_desc_cmd_vlan = 1,\n+    tx_desc_cmd_fcs = 2,\n+    tx_desc_cmd_ipv4 = 4,\n+    tx_desc_cmd_l4cs = 8,\n+    tx_desc_cmd_lso = 0x10,\n+    tx_desc_cmd_wb = 0x20,\n+};\n+\n+\n+/* Hardware rx descriptor */\n+struct hw_atl_rxd_s {\n+\tu64 buf_addr;\n+\tu64 hdr_addr;\n+} __attribute__((__packed__));\n+\n+/* Hardware rx descriptor writeback */\n+struct hw_atl_rxd_wb_s {\n+\tu32 rss_type:4;\n+\tu32 pkt_type:8;\n+\tu32 type:20;\n+\tu32 rss_hash;\n+\tu16 dd:1;\n+\tu16 eop:1;\n+\tu16 rx_stat:4;\n+\tu16 rx_estat:6;\n+\tu16 rsc_cnt:4;\n+\tu16 pkt_len;\n+\tu16 next_desc_ptr;\n+\tu16 vlan;\n+} __attribute__((__packed__));\n+\n+struct hw_atl_stats_s {\n+\tu32 uprc;\n+\tu32 mprc;\n+\tu32 bprc;\n+\tu32 erpt;\n+\tu32 uptc;\n+\tu32 mptc;\n+\tu32 bptc;\n+\tu32 erpr;\n+\tu32 mbtc;\n+\tu32 bbtc;\n+\tu32 mbrc;\n+\tu32 bbrc;\n+\tu32 ubrc;\n+\tu32 ubtc;\n+\tu32 dpc;\n+} __attribute__((__packed__));\n+\n+union ip_addr {\n+\tstruct {\n+\t\tu8 addr[16];\n+\t} v6;\n+\tstruct {\n+\t\tu8 padding[12];\n+\t\tu8 addr[4];\n+\t} v4;\n+} __attribute__((__packed__));\n+\n+struct hw_aq_atl_utils_fw_rpc {\n+\tu32 msg_id;\n+\n+\tunion {\n+\t\tstruct {\n+\t\t\tu32 pong;\n+\t\t} msg_ping;\n+\n+\t\tstruct {\n+\t\t\tu8 mac_addr[6];\n+\t\t\tu32 ip_addr_cnt;\n+\n+\t\t\tstruct {\n+\t\t\t\tunion ip_addr addr;\n+\t\t\t\tunion ip_addr mask;\n+\t\t\t} ip[1];\n+\t\t} msg_arp;\n+\n+\t\tstruct {\n+\t\t\tu32 len;\n+\t\t\tu8 packet[1514U];\n+\t\t} msg_inject;\n+\n+\t\tstruct {\n+\t\t\tu32 priority;\n+\t\t\tu32 wol_packet_type;\n+\t\t\tu32 pattern_id;\n+\t\t\tu32 next_wol_pattern_offset;\n+\t\t\tunion {\n+\t\t\t\tstruct {\n+\t\t\t\t\tu32 flags;\n+\t\t\t\t\tu8 ipv4_source_address[4];\n+\t\t\t\t\tu8 ipv4_dest_address[4];\n+\t\t\t\t\tu16 tcp_source_port_number;\n+\t\t\t\t\tu16 tcp_dest_port_number;\n+\t\t\t\t} ipv4_tcp_syn_parameters;\n+\n+\t\t\t\tstruct {\n+\t\t\t\t\tu32 flags;\n+\t\t\t\t\tu8 ipv6_source_address[16];\n+\t\t\t\t\tu8 ipv6_dest_address[16];\n+\t\t\t\t\tu16 tcp_source_port_number;\n+\t\t\t\t\tu16 tcp_dest_port_number;\n+\t\t\t\t} ipv6_tcp_syn_parameters;\n+\n+\t\t\t\tstruct {\n+\t\t\t\t\tu32 flags;\n+\t\t\t\t} eapol_request_id_message_parameters;\n+\n+\t\t\t\tstruct {\n+\t\t\t\t\tu32 flags;\n+\t\t\t\t\tu32 mask_offset;\n+\t\t\t\t\tu32 mask_size;\n+\t\t\t\t\tu32 pattern_offset;\n+\t\t\t\t\tu32 pattern_size;\n+\t\t\t\t} wol_bit_map_pattern;\n+\t\t\t\tstruct {\n+\t\t\t\t\tu8 mac_addr[6];\n+\t\t\t\t} wol_magic_packet_pattern;\n+\n+\t\t\t} wol_pattern;\n+\t\t} msg_wol;\n+\n+\t\tstruct {\n+\t\t\tu16 tcQuanta[8];\n+\t\t\tu16 tcThreshold[8];\n+\t\t} msg_msm_pfc_quantas;\n+\n+\t\tstruct {\n+\t\t\tunion {\n+\t\t\t\tu32 pattern_mask;\n+\t\t\t\tstruct {\n+\t\t\t\t\tu32 aq_pm_wol_reason_arp_v4_pkt : 1;\n+\t\t\t\t\tu32 aq_pm_wol_reason_ipv4_ping_pkt : 1;\n+\t\t\t\t\tu32 aq_pm_wol_reason_ipv6_ns_pkt : 1;\n+\t\t\t\t\tu32 aq_pm_wol_reason_ipv6_ping_pkt : 1;\n+\t\t\t\t\tu32 aq_pm_wol_reason_link_up : 1;\n+\t\t\t\t\tu32 aq_pm_wol_reason_link_down : 1;\n+\t\t\t\t\tu32 aq_pm_wol_reason_maximum : 1;\n+\t\t\t\t};\n+\t\t\t};\n+\t\t\tunion {\n+\t\t\t\tu32 offload_mask;\n+\t\t\t};\n+\t\t} msg_enable_wakeup;\n+\n+\t\tstruct {\n+\t\t\tu32 priority;\n+\t\t\tu32 protocol_offload_type;\n+\t\t\tu32 protocol_offload_id;\n+\t\t\tu32 next_protocol_offload_offset;\n+\n+\t\t\tunion {\n+\t\t\t\tstruct {\n+\t\t\t\t\tu32 flags;\n+\t\t\t\t\tu8 remote_ipv4_addr[4];\n+\t\t\t\t\tu8 host_ipv4_addr[4];\n+\t\t\t\t\tu8 mac_addr[6];\n+\t\t\t\t} ipv4_arp_params;\n+\t\t\t};\n+\t\t} msg_offload;\n+\n+\t\tstruct {\n+\t\t\tu32 id;\n+\t\t} msg_del_id;\n+\n+\t};\n+} __attribute__((__packed__));\n+\n+struct hw_aq_atl_utils_mbox_header {\n+\tu32 version;\n+\tu32 transaction_id;\n+\tu32 error;\n+} __attribute__((__packed__));\n+\n+struct hw_aq_info {\n+\tu8 reserved[6];\n+\tu16 phy_fault_code;\n+\tu16 phy_temperature;\n+\tu8 cable_len;\n+\tu8 reserved1;\n+\tu32 cable_diag_data[4];\n+\tu8 reserved2[32];\n+\tu32 caps_lo;\n+\tu32 caps_hi;\n+} __attribute__((__packed__));\n+\n+struct hw_aq_atl_utils_mbox {\n+\tstruct hw_aq_atl_utils_mbox_header header;\n+\tstruct hw_atl_stats_s stats;\n+\tstruct hw_aq_info info;\n+} __attribute__((__packed__));\n+\n+/* fw2x */\n+typedef u16\tin_port_t;\n+typedef u32\tip4_addr_t;\n+typedef int\tint32_t;\n+typedef short\tint16_t;\n+typedef u32\tfw_offset_t;\n+\n+struct ip6_addr {\n+\tu32 addr[4];\n+} __attribute__((__packed__));\n+\n+struct offload_ka_v4 {\n+\tu32 timeout;\n+\tin_port_t local_port;\n+\tin_port_t remote_port;\n+\tu8 remote_mac_addr[6];\n+\tu16 win_size;\n+\tu32 seq_num;\n+\tu32 ack_num;\n+\tip4_addr_t local_ip;\n+\tip4_addr_t remote_ip;\n+} __attribute__((__packed__));\n+\n+struct offload_ka_v6 {\n+\tu32 timeout;\n+\tin_port_t local_port;\n+\tin_port_t remote_port;\n+\tu8 remote_mac_addr[6];\n+\tu16 win_size;\n+\tu32 seq_num;\n+\tu32 ack_num;\n+\tstruct ip6_addr local_ip;\n+\tstruct ip6_addr remote_ip;\n+} __attribute__((__packed__));\n+\n+struct offload_ip_info {\n+\tu8 v4_local_addr_count;\n+\tu8 v4_addr_count;\n+\tu8 v6_local_addr_count;\n+\tu8 v6_addr_count;\n+\tfw_offset_t v4_addr;\n+\tfw_offset_t v4_prefix;\n+\tfw_offset_t v6_addr;\n+\tfw_offset_t v6_prefix;\n+} __attribute__((__packed__));\n+\n+struct offload_port_info {\n+\tu16 udp_port_count;\n+\tu16 tcp_port_count;\n+\tfw_offset_t udp_port;\n+\tfw_offset_t tcp_port;\n+} __attribute__((__packed__));\n+\n+struct offload_ka_info {\n+\tu16 v4_ka_count;\n+\tu16 v6_ka_count;\n+\tu32 retry_count;\n+\tu32 retry_interval;\n+\tfw_offset_t v4_ka;\n+\tfw_offset_t v6_ka;\n+} __attribute__((__packed__));\n+\n+struct offload_rr_info {\n+\tu32 rr_count;\n+\tu32 rr_buf_len;\n+\tfw_offset_t rr_id_x;\n+\tfw_offset_t rr_buf;\n+} __attribute__((__packed__));\n+\n+struct offload_info {\n+\tu32 version;\t\t// current version is 0x00000000\n+\tu32 len;\t\t// The whole structure length\n+\t\t\t\t// including the variable-size buf\n+\tu8 mac_addr[6];\t\t// 8 bytes to keep alignment. Only\n+\t\t\t\t// first 6 meaningful.\n+\n+\tu8 reserved[2];\n+\n+\tstruct offload_ip_info ips;\n+\tstruct offload_port_info ports;\n+\tstruct offload_ka_info kas;\n+\tstruct offload_rr_info rrs;\n+\tu8 buf[0];\n+} __attribute__((__packed__));\n+\n+struct smbus_read_request {\n+\tu32 offset; /* not used */\n+\tu32 device_id;\n+\tu32 address;\n+\tu32 length;\n+} __attribute__((__packed__));\n+\n+struct smbus_write_request {\n+\tu32 offset; /* not used */\n+\tu32 device_id;\n+\tu32 address;\n+\tu32 length;\n+} __attribute__((__packed__));\n+\n+#define HAL_ATLANTIC_UTILS_CHIP_MIPS         0x00000001U\n+#define HAL_ATLANTIC_UTILS_CHIP_TPO2         0x00000002U\n+#define HAL_ATLANTIC_UTILS_CHIP_RPF2         0x00000004U\n+#define HAL_ATLANTIC_UTILS_CHIP_MPI_AQ       0x00000010U\n+#define HAL_ATLANTIC_UTILS_CHIP_REVISION_A0  0x01000000U\n+#define HAL_ATLANTIC_UTILS_CHIP_REVISION_B0  0x02000000U\n+#define HAL_ATLANTIC_UTILS_CHIP_REVISION_B1  0x04000000U\n+\n+\n+#define IS_CHIP_FEATURE(_F_) (HAL_ATLANTIC_UTILS_CHIP_##_F_ & \\\n+\tself->chip_features)\n+\n+enum hal_atl_utils_fw_state_e {\n+\tMPI_DEINIT = 0,\n+\tMPI_RESET = 1,\n+\tMPI_INIT = 2,\n+\tMPI_POWER = 4,\n+};\n+\n+#define HAL_ATLANTIC_RATE_10G        BIT(0)\n+#define HAL_ATLANTIC_RATE_5G         BIT(1)\n+#define HAL_ATLANTIC_RATE_5GSR       BIT(2)\n+#define HAL_ATLANTIC_RATE_2GS        BIT(3)\n+#define HAL_ATLANTIC_RATE_1G         BIT(4)\n+#define HAL_ATLANTIC_RATE_100M       BIT(5)\n+#define HAL_ATLANTIC_RATE_INVALID    BIT(6)\n+\n+#define HAL_ATLANTIC_UTILS_FW_MSG_PING     1U\n+#define HAL_ATLANTIC_UTILS_FW_MSG_ARP      2U\n+#define HAL_ATLANTIC_UTILS_FW_MSG_INJECT   3U\n+#define HAL_ATLANTIC_UTILS_FW_MSG_WOL_ADD 4U\n+#define HAL_ATLANTIC_UTILS_FW_MSG_WOL_DEL 5U\n+#define HAL_ATLANTIC_UTILS_FW_MSG_ENABLE_WAKEUP 6U\n+#define HAL_ATLANTIC_UTILS_FW_MSG_MSM_PFC  7U\n+#define HAL_ATLANTIC_UTILS_FW_MSG_PROVISIONING 8U\n+#define HAL_ATLANTIC_UTILS_FW_MSG_OFFLOAD_ADD  9U\n+#define HAL_ATLANTIC_UTILS_FW_MSG_OFFLOAD_DEL  10U\n+#define HAL_ATLANTIC_UTILS_FW_MSG_CABLE_DIAG   13U // 0xd\n+\n+#define SMBUS_READ_REQUEST BIT(13)\n+#define SMBUS_WRITE_REQUEST BIT(14)\n+#define SMBUS_DEVICE_ID 0x50\n+\n+enum hw_atl_fw2x_rate {\n+\tFW2X_RATE_100M    = 0x20,\n+\tFW2X_RATE_1G      = 0x100,\n+\tFW2X_RATE_2G5     = 0x200,\n+\tFW2X_RATE_5G      = 0x400,\n+\tFW2X_RATE_10G     = 0x800,\n+};\n+\n+enum hw_atl_fw2x_caps_lo {\n+\tCAPS_LO_10BASET_HD = 0x00,\n+\tCAPS_LO_10BASET_FD,\n+\tCAPS_LO_100BASETX_HD,\n+\tCAPS_LO_100BASET4_HD,\n+\tCAPS_LO_100BASET2_HD,\n+\tCAPS_LO_100BASETX_FD,\n+\tCAPS_LO_100BASET2_FD,\n+\tCAPS_LO_1000BASET_HD,\n+\tCAPS_LO_1000BASET_FD,\n+\tCAPS_LO_2P5GBASET_FD,\n+\tCAPS_LO_5GBASET_FD,\n+\tCAPS_LO_10GBASET_FD,\n+};\n+\n+enum hw_atl_fw2x_caps_hi {\n+\tCAPS_HI_RESERVED1 = 0x00,\n+\tCAPS_HI_10BASET_EEE,\n+\tCAPS_HI_RESERVED2,\n+\tCAPS_HI_PAUSE,\n+\tCAPS_HI_ASYMMETRIC_PAUSE,\n+\tCAPS_HI_100BASETX_EEE,\n+\tCAPS_HI_RESERVED3,\n+\tCAPS_HI_RESERVED4,\n+\tCAPS_HI_1000BASET_FD_EEE,\n+\tCAPS_HI_2P5GBASET_FD_EEE,\n+\tCAPS_HI_5GBASET_FD_EEE,\n+\tCAPS_HI_10GBASET_FD_EEE,\n+\tCAPS_HI_RESERVED5,\n+\tCAPS_HI_RESERVED6,\n+\tCAPS_HI_RESERVED7,\n+\tCAPS_HI_RESERVED8,\n+\tCAPS_HI_RESERVED9,\n+\tCAPS_HI_CABLE_DIAG,\n+\tCAPS_HI_TEMPERATURE,\n+\tCAPS_HI_DOWNSHIFT,\n+\tCAPS_HI_PTP_AVB_EN,\n+\tCAPS_HI_MEDIA_DETECT,\n+\tCAPS_HI_LINK_DROP,\n+\tCAPS_HI_SLEEP_PROXY,\n+\tCAPS_HI_WOL,\n+\tCAPS_HI_MAC_STOP,\n+\tCAPS_HI_EXT_LOOPBACK,\n+\tCAPS_HI_INT_LOOPBACK,\n+\tCAPS_HI_EFUSE_AGENT,\n+\tCAPS_HI_WOL_TIMER,\n+\tCAPS_HI_STATISTICS,\n+\tCAPS_HI_TRANSACTION_ID,\n+};\n+\n+struct aq_hw_s;\n+struct aq_fw_ops;\n+struct aq_hw_link_status_s;\n+\n+int hw_atl_utils_initfw(struct aq_hw_s *self, const struct aq_fw_ops **fw_ops);\n+\n+int hw_atl_utils_soft_reset(struct aq_hw_s *self);\n+\n+void hw_atl_utils_hw_chip_features_init(struct aq_hw_s *self, u32 *p);\n+\n+int hw_atl_utils_mpi_read_mbox(struct aq_hw_s *self,\n+\t\t\t       struct hw_aq_atl_utils_mbox_header *pmbox);\n+\n+void hw_atl_utils_mpi_read_stats(struct aq_hw_s *self,\n+\t\t\t\t struct hw_aq_atl_utils_mbox *pmbox);\n+\n+void hw_atl_utils_mpi_set(struct aq_hw_s *self,\n+\t\t\t  enum hal_atl_utils_fw_state_e state,\n+\t\t\t  u32 speed);\n+\n+int hw_atl_utils_mpi_get_link_status(struct aq_hw_s *self);\n+\n+unsigned int hw_atl_utils_mbps_2_speed_index(unsigned int mbps);\n+\n+unsigned int hw_atl_utils_hw_get_reg_length(void);\n+\n+int hw_atl_utils_hw_get_regs(struct aq_hw_s *self,\n+\t\t\t     u32 *regs_buff);\n+\n+int hw_atl_utils_hw_set_power(struct aq_hw_s *self,\n+\t\t\t      unsigned int power_state);\n+\n+int hw_atl_utils_hw_deinit(struct aq_hw_s *self);\n+\n+int hw_atl_utils_get_fw_version(struct aq_hw_s *self, u32 *fw_version);\n+\n+int hw_atl_utils_update_stats(struct aq_hw_s *self);\n+\n+struct aq_stats_s *hw_atl_utils_get_hw_stats(struct aq_hw_s *self);\n+\n+int hw_atl_utils_fw_downld_dwords(struct aq_hw_s *self, u32 a,\n+\t\t\t\t  u32 *p, u32 cnt);\n+\n+int hw_atl_utils_fw_upload_dwords(struct aq_hw_s *self, u32 a, u32 *p,\n+\t\t\t\tu32 cnt);\n+\n+int hw_atl_utils_fw_set_wol(struct aq_hw_s *self, bool wol_enabled, u8 *mac);\n+\n+int hw_atl_utils_fw_rpc_call(struct aq_hw_s *self, unsigned int rpc_size);\n+\n+int hw_atl_utils_fw_rpc_wait(struct aq_hw_s *self,\n+\t\t    struct hw_aq_atl_utils_fw_rpc **rpc);\n+\n+extern const struct aq_fw_ops aq_fw_1x_ops;\n+extern const struct aq_fw_ops aq_fw_2x_ops;\n+\n+#endif /* HW_ATL_UTILS_H */\ndiff --git a/drivers/net/atlantic/hw_atl/hw_atl_utils_fw2x.c b/drivers/net/atlantic/hw_atl/hw_atl_utils_fw2x.c\nnew file mode 100644\nindex 000000000..0fe118aab\n--- /dev/null\n+++ b/drivers/net/atlantic/hw_atl/hw_atl_utils_fw2x.c\n@@ -0,0 +1,623 @@\n+/*\n+ * aQuantia Corporation Network Driver\n+ * Copyright (C) 2014-2017 aQuantia Corporation. All rights reserved\n+ *\n+ * This program is free software; you can redistribute it and/or modify it\n+ * under the terms and conditions of the GNU General Public License,\n+ * version 2, as published by the Free Software Foundation.\n+ */\n+\n+/* File hw_atl_utils_fw2x.c: Definition of firmware 2.x functions for\n+ * Atlantic hardware abstraction layer.\n+ */\n+\n+#include <rte_ether.h>\n+#include \"../atl_hw_regs.h\"\n+\n+#include \"../atl_types.h\"\n+#include \"hw_atl_utils.h\"\n+#include \"hw_atl_llh.h\"\n+\n+#define HW_ATL_FW2X_MPI_EFUSE_ADDR\t0x364\n+#define HW_ATL_FW2X_MPI_MBOX_ADDR\t0x360\n+#define HW_ATL_FW2X_MPI_RPC_ADDR\t0x334\n+\n+#define HW_ATL_FW2X_MPI_CONTROL_ADDR\t0x368\n+#define HW_ATL_FW2X_MPI_CONTROL2_ADDR\t0x36C\n+#define HW_ATL_FW2X_MPI_LED_ADDR\t0x31c\n+\n+#define HW_ATL_FW2X_MPI_STATE_ADDR\t0x370\n+#define HW_ATL_FW2X_MPI_STATE2_ADDR\t0x374\n+\n+#define HW_ATL_FW2X_CAP_SLEEP_PROXY BIT(CAPS_HI_SLEEP_PROXY)\n+#define HW_ATL_FW2X_CAP_WOL BIT(CAPS_HI_WOL)\n+\n+#define HW_ATL_FW2X_CAP_EEE_1G_MASK   BIT(CAPS_HI_1000BASET_FD_EEE)\n+#define HW_ATL_FW2X_CAP_EEE_2G5_MASK  BIT(CAPS_HI_2P5GBASET_FD_EEE)\n+#define HW_ATL_FW2X_CAP_EEE_5G_MASK   BIT(CAPS_HI_5GBASET_FD_EEE)\n+#define HW_ATL_FW2X_CAP_EEE_10G_MASK  BIT(CAPS_HI_10GBASET_FD_EEE)\n+\n+#define HAL_ATLANTIC_WOL_FILTERS_COUNT     8\n+#define HAL_ATLANTIC_UTILS_FW2X_MSG_WOL    0x0E\n+\n+#define HW_ATL_FW_FEATURE_EEPROM 0x03010025\n+#define HW_ATL_FW_FEATURE_LED 0x03010026\n+\n+struct fw2x_msg_wol_pattern {\n+\tu8 mask[16];\n+\tu32 crc;\n+} __attribute__((__packed__));\n+\n+struct fw2x_msg_wol {\n+\tu32 msg_id;\n+\tu8 hw_addr[6];\n+\tu8 magic_packet_enabled;\n+\tu8 filter_count;\n+\tstruct fw2x_msg_wol_pattern filter[HAL_ATLANTIC_WOL_FILTERS_COUNT];\n+\tu8 link_up_enabled;\n+\tu8 link_down_enabled;\n+\tu16 reserved;\n+\tu32 link_up_timeout;\n+\tu32 link_down_timeout;\n+} __attribute__((__packed__));\n+\n+static int aq_fw2x_set_link_speed(struct aq_hw_s *self, u32 speed);\n+static int aq_fw2x_set_state(struct aq_hw_s *self,\n+\t\t\t     enum hal_atl_utils_fw_state_e state);\n+\n+static int aq_fw2x_init(struct aq_hw_s *self)\n+{\n+\tint err = 0;\n+\n+\t/* check 10 times by 1ms */\n+\tAQ_HW_WAIT_FOR(0U != (self->mbox_addr =\n+\t\t       aq_hw_read_reg(self, HW_ATL_FW2X_MPI_MBOX_ADDR)),\n+\t\t       1000U, 10U);\n+\tAQ_HW_WAIT_FOR(0U != (self->rpc_addr =\n+\t\t       aq_hw_read_reg(self, HW_ATL_FW2X_MPI_RPC_ADDR)),\n+\t\t       1000U, 100U);\n+\treturn err;\n+}\n+\n+static int aq_fw2x_deinit(struct aq_hw_s *self)\n+{\n+\tint err = aq_fw2x_set_link_speed(self, 0);\n+\n+\tif (!err)\n+\t\terr = aq_fw2x_set_state(self, MPI_DEINIT);\n+\n+\treturn err;\n+}\n+\n+static enum hw_atl_fw2x_rate link_speed_mask_2fw2x_ratemask(u32 speed)\n+{\n+\tenum hw_atl_fw2x_rate rate = 0;\n+\n+\tif (speed & AQ_NIC_RATE_10G)\n+\t\trate |= FW2X_RATE_10G;\n+\n+\tif (speed & AQ_NIC_RATE_5G)\n+\t\trate |= FW2X_RATE_5G;\n+\n+\tif (speed & AQ_NIC_RATE_5G5R)\n+\t\trate |= FW2X_RATE_5G;\n+\n+\tif (speed & AQ_NIC_RATE_2G5)\n+\t\trate |= FW2X_RATE_2G5;\n+\n+\tif (speed & AQ_NIC_RATE_1G)\n+\t\trate |= FW2X_RATE_1G;\n+\n+\tif (speed & AQ_NIC_RATE_100M)\n+\t\trate |= FW2X_RATE_100M;\n+\n+\treturn rate;\n+}\n+\n+static u32 fw2x_to_eee_mask(u32 speed)\n+{\n+\tu32 rate = 0;\n+\n+\tif (speed & HW_ATL_FW2X_CAP_EEE_10G_MASK)\n+\t\trate |= AQ_NIC_RATE_EEE_10G;\n+\n+\tif (speed & HW_ATL_FW2X_CAP_EEE_5G_MASK)\n+\t\trate |= AQ_NIC_RATE_EEE_5G;\n+\n+\tif (speed & HW_ATL_FW2X_CAP_EEE_2G5_MASK)\n+\t\trate |= AQ_NIC_RATE_EEE_2G5;\n+\n+\tif (speed & HW_ATL_FW2X_CAP_EEE_1G_MASK)\n+\t\trate|= AQ_NIC_RATE_EEE_1G;\n+\n+\treturn rate;\n+}\n+\n+static int aq_fw2x_set_link_speed(struct aq_hw_s *self, u32 speed)\n+{\n+\tu32 val = link_speed_mask_2fw2x_ratemask(speed);\n+\n+\taq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL_ADDR, val);\n+\n+\treturn 0;\n+}\n+\n+static void aq_fw2x_set_mpi_flow_control(struct aq_hw_s *self, u32 *mpi_state)\n+{\n+\tif (self->aq_nic_cfg->flow_control & AQ_NIC_FC_RX)\n+\t\t*mpi_state |= BIT(CAPS_HI_PAUSE);\n+\telse\n+\t\t*mpi_state &= ~BIT(CAPS_HI_PAUSE);\n+\n+\tif (self->aq_nic_cfg->flow_control & AQ_NIC_FC_TX)\n+\t\t*mpi_state |= BIT(CAPS_HI_ASYMMETRIC_PAUSE);\n+\telse\n+\t\t*mpi_state &= ~BIT(CAPS_HI_ASYMMETRIC_PAUSE);\n+}\n+\n+static int aq_fw2x_set_state(struct aq_hw_s *self,\n+\t\t\t     enum hal_atl_utils_fw_state_e state)\n+{\n+\tu32 mpi_state = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR);\n+\n+\tswitch(state) {\n+\tcase MPI_INIT:\n+\t\tmpi_state &= ~BIT(CAPS_HI_LINK_DROP);\n+/*\t\tif (self->aq_nic_cfg->flow_control & AQ_NIC_FC_RX)\n+\t\t\tmpi_state |= BIT(CAPS_HI_PAUSE);\n+\t\tif (self->aq_nic_cfg->flow_control & AQ_NIC_FC_TX)\n+\t\t\tmpi_state |= BIT(CAPS_HI_ASYMMETRIC_PAUSE);\n+*/\n+\t\taq_fw2x_set_mpi_flow_control(self, &mpi_state);\n+\t\tbreak;\n+\tcase MPI_DEINIT:\n+\t\tmpi_state |= BIT(CAPS_HI_LINK_DROP);\n+\t\tbreak;\n+\tcase MPI_RESET:\n+\tcase MPI_POWER:\n+\t\t/* No actions */\n+\t\tbreak;\n+\t}\n+\taq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR, mpi_state);\n+\treturn 0;\n+}\n+\n+static int aq_fw2x_update_link_status(struct aq_hw_s *self)\n+{\n+\tu32 mpi_state = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_STATE_ADDR);\n+\tu32 speed = mpi_state & (FW2X_RATE_100M | FW2X_RATE_1G |\n+\t\t\t\tFW2X_RATE_2G5 | FW2X_RATE_5G | FW2X_RATE_10G);\n+\tstruct aq_hw_link_status_s *link_status = &self->aq_link_status;\n+\n+\tif (speed) {\n+\t\tif (speed & FW2X_RATE_10G)\n+\t\t\tlink_status->mbps = 10000;\n+\t\telse if (speed & FW2X_RATE_5G)\n+\t\t\tlink_status->mbps = 5000;\n+\t\telse if (speed & FW2X_RATE_2G5)\n+\t\t\tlink_status->mbps = 2500;\n+\t\telse if (speed & FW2X_RATE_1G)\n+\t\t\tlink_status->mbps = 1000;\n+\t\telse if (speed & FW2X_RATE_100M)\n+\t\t\tlink_status->mbps = 100;\n+\t\telse\n+\t\t\tlink_status->mbps = 10000;\n+\t} else {\n+\t\tlink_status->mbps = 0;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static\n+int aq_fw2x_get_mac_permanent(struct aq_hw_s *self, u8 *mac)\n+{\n+\tint err = 0;\n+\tu32 h = 0U;\n+\tu32 l = 0U;\n+\tu32 mac_addr[2] = { 0 };\n+\tu32 efuse_addr = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_EFUSE_ADDR);\n+\n+\tif (efuse_addr != 0) {\n+\t\terr = hw_atl_utils_fw_downld_dwords(self,\n+\t\t\t\t\t\t    efuse_addr + (40U * 4U),\n+\t\t\t\t\t\t    mac_addr,\n+\t\t\t\t\t\t    ARRAY_SIZE(mac_addr));\n+\t\tif (err)\n+\t\t\treturn err;\n+\t\tmac_addr[0] = rte_constant_bswap32(mac_addr[0]);\n+\t\tmac_addr[1] = rte_constant_bswap32(mac_addr[1]);\n+\t}\n+\n+\tether_addr_copy((struct ether_addr *)mac_addr, (struct ether_addr *)mac);\n+\n+\tif ((mac[0] & 0x01U) || ((mac[0] | mac[1] | mac[2]) == 0x00U)) {\n+\t\tunsigned int rnd = (uint32_t)rte_rand();\n+\n+\t\t//get_random_bytes(&rnd, sizeof(unsigned int));\n+\n+\t\tl = 0xE3000000U\n+\t\t\t| (0xFFFFU & rnd)\n+\t\t\t| (0x00 << 16);\n+\t\th = 0x8001300EU;\n+\n+\t\tmac[5] = (u8)(0xFFU & l);\n+\t\tl >>= 8;\n+\t\tmac[4] = (u8)(0xFFU & l);\n+\t\tl >>= 8;\n+\t\tmac[3] = (u8)(0xFFU & l);\n+\t\tl >>= 8;\n+\t\tmac[2] = (u8)(0xFFU & l);\n+\t\tmac[1] = (u8)(0xFFU & h);\n+\t\th >>= 8;\n+\t\tmac[0] = (u8)(0xFFU & h);\n+\t}\n+\treturn err;\n+}\n+\n+static int aq_fw2x_update_stats(struct aq_hw_s *self)\n+{\n+\tint err = 0;\n+\tu32 mpi_opts = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR);\n+\tu32 orig_stats_val = mpi_opts & BIT(CAPS_HI_STATISTICS);\n+\n+\t/* Toggle statistics bit for FW to update */\n+\tmpi_opts = mpi_opts ^ BIT(CAPS_HI_STATISTICS);\n+\taq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR, mpi_opts);\n+\n+\t/* Wait FW to report back */\n+\tAQ_HW_WAIT_FOR(orig_stats_val !=\n+\t\t       (aq_hw_read_reg(self, HW_ATL_FW2X_MPI_STATE2_ADDR) &\n+\t\t\t\t       BIT(CAPS_HI_STATISTICS)),\n+\t\t       1U, 10000U);\n+\tif (err)\n+\t\treturn err;\n+\n+\treturn hw_atl_utils_update_stats(self);\n+}\n+\n+static int aq_fw2x_get_temp(struct aq_hw_s *self, int *temp)\n+{\n+\tint err = 0;\n+\tu32 mpi_opts = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR);\n+\tu32 temp_val = mpi_opts & BIT(CAPS_HI_TEMPERATURE);\n+\tu32 temp_res;\n+\n+\t/* Toggle statistics bit for FW to 0x36C.18 (CAPS_HI_TEMPERATURE) */\n+\tmpi_opts = mpi_opts ^ BIT(CAPS_HI_TEMPERATURE);\n+\taq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR, mpi_opts);\n+\n+\t/* Wait FW to report back */\n+\tAQ_HW_WAIT_FOR(temp_val !=\n+\t\t\t(aq_hw_read_reg(self, HW_ATL_FW2X_MPI_STATE2_ADDR) &\n+\t\t\t\t\tBIT(CAPS_HI_TEMPERATURE)), 1U, 10000U);\n+\terr = hw_atl_utils_fw_downld_dwords(self,\n+\t\t\t\tself->mbox_addr +\n+\t\t\t\toffsetof(struct hw_aq_atl_utils_mbox, info) +\n+\t\t\t\toffsetof(struct hw_aq_info, phy_temperature),\n+\t\t\t\t&temp_res,\n+\t\t\t\tsizeof(temp_res)/sizeof(u32));\n+\n+\tif (err)\n+\t\treturn err;\n+\n+\t*temp = temp_res  * 100 / 256;\n+\treturn 0;\n+}\n+\n+static int aq_fw2x_get_cable_len(struct aq_hw_s *self, int *cable_len)\n+{\n+\tint err = 0;\n+\tu32 cable_len_res;\n+\n+\terr = hw_atl_utils_fw_downld_dwords(self,\n+\t\t\t\tself->mbox_addr +\n+\t\t\t\toffsetof(struct hw_aq_atl_utils_mbox, info) +\n+\t\t\t\toffsetof(struct hw_aq_info, phy_temperature),\n+\t\t\t\t&cable_len_res,\n+\t\t\t\tsizeof(cable_len_res)/sizeof(u32));\n+\n+\tif (err)\n+\t\treturn err;\n+\n+\t*cable_len = (cable_len_res >> 16) & 0xFF;\n+\treturn 0;\n+}\n+\n+#ifndef ETH_ALEN\n+#define ETH_ALEN 6\n+#endif\n+\n+static int aq_fw2x_set_sleep_proxy(struct aq_hw_s *self, u8 *mac)\n+{\n+\tint err = 0;\n+\tstruct hw_aq_atl_utils_fw_rpc *rpc = NULL;\n+\tstruct offload_info *cfg = NULL;\n+\tunsigned int rpc_size = 0U;\n+\tu32 mpi_opts;\n+\n+\trpc_size = sizeof(rpc->msg_id) + sizeof(*cfg);\n+\n+\terr = hw_atl_utils_fw_rpc_wait(self, &rpc);\n+\tif (err < 0)\n+\t\tgoto err_exit;\n+\n+\tmemset(rpc, 0, rpc_size);\n+\tcfg = (struct offload_info *)(&rpc->msg_id + 1);\n+\n+\tmemcpy(cfg->mac_addr, mac, ETH_ALEN);\n+\tcfg->len = sizeof(*cfg);\n+\n+\t/* Clear bit 0x36C.23 */\n+\tmpi_opts = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR);\n+\tmpi_opts &= ~HW_ATL_FW2X_CAP_SLEEP_PROXY;\n+\n+\taq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR, mpi_opts);\n+\n+\terr = hw_atl_utils_fw_rpc_call(self, rpc_size);\n+\tif (err < 0)\n+\t\tgoto err_exit;\n+\n+\t/* Set bit 0x36C.23 */\n+\tmpi_opts |= HW_ATL_FW2X_CAP_SLEEP_PROXY;\n+\taq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR, mpi_opts);\n+\n+\tAQ_HW_WAIT_FOR((aq_hw_read_reg(self, HW_ATL_FW2X_MPI_STATE2_ADDR) &\n+\t\t\tHW_ATL_FW2X_CAP_SLEEP_PROXY), 1U, 10000U);\n+err_exit:\n+\treturn err;\n+}\n+\n+static int aq_fw2x_set_wol_params(struct aq_hw_s *self, u8 *mac)\n+{\n+\tint err = 0;\n+\tstruct fw2x_msg_wol *msg = NULL;\n+\tu32 mpi_opts;\n+\n+\tstruct hw_aq_atl_utils_fw_rpc *rpc = NULL;\n+\n+\terr = hw_atl_utils_fw_rpc_wait(self, &rpc);\n+\tif (err < 0)\n+\t\tgoto err_exit;\n+\n+\tmsg = (struct fw2x_msg_wol *)rpc;\n+\n+\tmsg->msg_id = HAL_ATLANTIC_UTILS_FW2X_MSG_WOL;\n+\tmsg->magic_packet_enabled = true;\n+\tmemcpy(msg->hw_addr, mac, ETH_ALEN);\n+\n+\tmpi_opts = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR);\n+\tmpi_opts &= ~(HW_ATL_FW2X_CAP_SLEEP_PROXY | HW_ATL_FW2X_CAP_WOL);\n+\n+\taq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR, mpi_opts);\n+\n+\terr = hw_atl_utils_fw_rpc_call(self, sizeof(*msg));\n+\tif (err < 0)\n+\t\tgoto err_exit;\n+\n+\t/* Set bit 0x36C.24 */\n+\tmpi_opts |= HW_ATL_FW2X_CAP_WOL;\n+\taq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR, mpi_opts);\n+\n+\tAQ_HW_WAIT_FOR((aq_hw_read_reg(self, HW_ATL_FW2X_MPI_STATE2_ADDR) &\n+\t\t\tHW_ATL_FW2X_CAP_WOL), 1U, 10000U);\n+err_exit:\n+\treturn err;\n+}\n+\n+static int aq_fw2x_set_power(struct aq_hw_s *self, unsigned int power_state __rte_unused,\n+\t\t\t\tu8 *mac)\n+{\n+\tint err = 0;\n+\n+\tif (self->aq_nic_cfg->wol & AQ_NIC_WOL_ENABLED) {\n+\t\terr = aq_fw2x_set_sleep_proxy(self, mac);\n+\t\tif (err < 0)\n+\t\t\tgoto err_exit;\n+\t\terr = aq_fw2x_set_wol_params(self, mac);\n+\t\tif (err < 0)\n+\t\t\tgoto err_exit;\n+\t}\n+err_exit:\n+\treturn err;\n+}\n+\n+static int aq_fw2x_set_eee_rate(struct aq_hw_s *self, u32 speed)\n+{\n+\tu32 mpi_opts = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR);\n+\tmpi_opts &= ~(HW_ATL_FW2X_CAP_EEE_1G_MASK |\n+\t\tHW_ATL_FW2X_CAP_EEE_2G5_MASK | HW_ATL_FW2X_CAP_EEE_5G_MASK |\n+\t\tHW_ATL_FW2X_CAP_EEE_10G_MASK);\n+\n+\tif (speed & AQ_NIC_RATE_EEE_10G)\n+\t\tmpi_opts |= HW_ATL_FW2X_CAP_EEE_10G_MASK;\n+\n+\tif (speed & AQ_NIC_RATE_EEE_5G)\n+\t\tmpi_opts |= HW_ATL_FW2X_CAP_EEE_5G_MASK;\n+\n+\tif (speed & AQ_NIC_RATE_EEE_2G5)\n+\t\tmpi_opts |= HW_ATL_FW2X_CAP_EEE_2G5_MASK;\n+\n+\tif (speed & AQ_NIC_RATE_EEE_1G)\n+\t\tmpi_opts |= HW_ATL_FW2X_CAP_EEE_1G_MASK;\n+\n+\taq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR, mpi_opts);\n+\n+\treturn 0;\n+}\n+\n+static int aq_fw2x_get_eee_rate(struct aq_hw_s *self, u32 *rate,\n+\t\t\t\t\tu32 *supported_rates)\n+{\n+\tint err = 0;\n+\tu32 caps_hi;\n+\tu32 mpi_state;\n+\n+\terr = hw_atl_utils_fw_downld_dwords(self,\n+\t\t\t\tself->mbox_addr +\n+\t\t\t\toffsetof(struct hw_aq_atl_utils_mbox, info) +\n+\t\t\t\toffsetof(struct hw_aq_info, caps_hi),\n+\t\t\t\t&caps_hi,\n+\t\t\t\tsizeof(caps_hi)/sizeof(u32));\n+\n+\tif (err)\n+\t\treturn err;\n+\n+\t*supported_rates = fw2x_to_eee_mask(caps_hi);\n+\n+\tmpi_state = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_STATE2_ADDR);\n+\t*rate = fw2x_to_eee_mask(mpi_state);\n+\n+\treturn err;\n+}\n+\n+\n+\n+static int aq_fw2x_set_flow_control(struct aq_hw_s *self)\n+{\n+\tu32 mpi_state = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR);\n+\n+\taq_fw2x_set_mpi_flow_control(self, &mpi_state);\n+\n+\taq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR, mpi_state);\n+\n+\treturn 0;\n+}\n+\n+static int aq_fw2x_led_control(struct aq_hw_s *self, u32 mode)\n+{\n+\tif (HW_ATL_FW_FEATURE_LED > self->fw_ver_actual)\n+\t\treturn -EOPNOTSUPP;\n+\n+\taq_hw_write_reg(self, HW_ATL_FW2X_MPI_LED_ADDR, mode);\n+\treturn 0;\n+}\n+\n+static int aq_fw2x_get_eeprom(struct aq_hw_s *self, u32 *data, u32 len)\n+{\n+\tint err = 0;\n+\tstruct smbus_read_request request;\n+\tu32 mpi_opts;\n+\tu32 result = 0;\n+\n+\tif (HW_ATL_FW_FEATURE_EEPROM > self->fw_ver_actual)\n+\t\treturn -EOPNOTSUPP;\n+\n+\trequest.device_id = SMBUS_DEVICE_ID;\n+\trequest.address = 0;\n+\trequest.length = len;\n+\n+\t/* Write SMBUS request to cfg memory */\n+\terr = hw_atl_utils_fw_upload_dwords(self, self->rpc_addr,\n+\t\t\t\t(u32 *)(void *)&request,\n+\t\t\t\tRTE_ALIGN(sizeof(request), sizeof(u32)));\n+\n+\tif (err < 0)\n+\t\treturn err;\n+\n+\t/* Toggle 0x368.SMBUS_READ_REQUEST bit */\n+\tmpi_opts = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_CONTROL_ADDR);\n+\tmpi_opts ^= SMBUS_READ_REQUEST;\n+\n+\taq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL_ADDR, mpi_opts);\n+\n+\t/* Wait until REQUEST_BIT matched in 0x370 */\n+\n+\tAQ_HW_WAIT_FOR((aq_hw_read_reg(self, HW_ATL_FW2X_MPI_STATE_ADDR) &\n+\t\tSMBUS_READ_REQUEST) == (mpi_opts & SMBUS_READ_REQUEST), 10U, 10000U);\n+\n+\tif (err < 0)\n+\t\treturn err;\n+\n+\terr = hw_atl_utils_fw_downld_dwords(self, self->rpc_addr + sizeof(u32),\n+\t\t\t&result,\n+\t\t\tRTE_ALIGN(sizeof(result), sizeof(u32)));\n+\n+\tif (err < 0)\n+\t\treturn err;\n+\n+\tif (result == 0) {\n+\t\terr = hw_atl_utils_fw_downld_dwords(self, self->rpc_addr + sizeof(u32)*2,\n+\t\t\tdata,\n+\t\t\tRTE_ALIGN(len, sizeof(u32)));\n+\n+\t\tif (err < 0)\n+\t\t\treturn err;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+\n+static int aq_fw2x_set_eeprom(struct aq_hw_s *self, u32 *data, u32 len)\n+{\n+\tstruct smbus_write_request request;\n+\tu32 mpi_opts, result = 0;\n+\tint err = 0;\n+\n+\tif (HW_ATL_FW_FEATURE_EEPROM > self->fw_ver_actual)\n+\t\treturn -EOPNOTSUPP;\n+\n+\trequest.device_id = SMBUS_DEVICE_ID;\n+\trequest.address = 0;\n+\trequest.length = len;\n+\n+\t/* Write SMBUS request to cfg memory */\n+\terr = hw_atl_utils_fw_upload_dwords(self, self->rpc_addr,\n+\t\t\t\t(u32 *)(void *)&request,\n+\t\t\t\tRTE_ALIGN(sizeof(request), sizeof(u32)));\n+\n+\tif (err < 0)\n+\t\treturn err;\n+\n+\t/* Write SMBUS data to cfg memory */\n+\terr = hw_atl_utils_fw_upload_dwords(self, self->rpc_addr + sizeof(request),\n+\t\t\t\t(u32 *)(void *)data,\n+\t\t\t\tRTE_ALIGN(len, sizeof(u32)));\n+\n+\tif (err < 0)\n+\t\treturn err;\n+\n+\t/* Toggle 0x368.SMBUS_WRITE_REQUEST bit */\n+\tmpi_opts = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_CONTROL_ADDR);\n+\tmpi_opts ^= SMBUS_WRITE_REQUEST;\n+\n+\taq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL_ADDR, mpi_opts);\n+\n+\t/* Wait until REQUEST_BIT matched in 0x370 */\n+\tAQ_HW_WAIT_FOR((aq_hw_read_reg(self, HW_ATL_FW2X_MPI_STATE_ADDR) &\n+\t\tSMBUS_WRITE_REQUEST) == (mpi_opts & SMBUS_WRITE_REQUEST), 10U, 10000U);\n+\n+\tif (err < 0)\n+\t\treturn err;\n+\n+\t/* Read status of write operation */\n+\terr = hw_atl_utils_fw_downld_dwords(self, self->rpc_addr + sizeof(u32),\n+\t\t\t\t&result,\n+\t\t\t\tRTE_ALIGN(sizeof(result), sizeof(u32)));\n+\n+\tif (err < 0)\n+\t\treturn err;\n+\n+\treturn 0;\n+}\n+\n+const struct aq_fw_ops aq_fw_2x_ops = {\n+\t.init = aq_fw2x_init,\n+\t.deinit = aq_fw2x_deinit,\n+\t.reset = NULL,\n+\t.get_mac_permanent = aq_fw2x_get_mac_permanent,\n+\t.set_link_speed = aq_fw2x_set_link_speed,\n+\t.set_state = aq_fw2x_set_state,\n+\t.update_link_status = aq_fw2x_update_link_status,\n+\t.update_stats = aq_fw2x_update_stats,\n+\t.set_power = aq_fw2x_set_power,\n+\t.get_temp = aq_fw2x_get_temp,\n+\t.get_cable_len = aq_fw2x_get_cable_len,\n+\t.set_eee_rate = aq_fw2x_set_eee_rate,\n+\t.get_eee_rate = aq_fw2x_get_eee_rate,\n+\t.set_flow_control = aq_fw2x_set_flow_control,\n+\t.led_control = aq_fw2x_led_control,\n+\t.get_eeprom = aq_fw2x_get_eeprom,\n+\t.set_eeprom = aq_fw2x_set_eeprom,\n+};\n",
    "prefixes": [
        "06/21"
    ]
}