get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 46700,
    "url": "http://patches.dpdk.org/api/patches/46700/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/8e0e8eb1e71d73521b8dc8f272f6fa3cc222df9a.1539338074.git.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": "<8e0e8eb1e71d73521b8dc8f272f6fa3cc222df9a.1539338074.git.igor.russkikh@aquantia.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/8e0e8eb1e71d73521b8dc8f272f6fa3cc222df9a.1539338074.git.igor.russkikh@aquantia.com",
    "date": "2018-10-12T11:09:14",
    "name": "[v6,05/22] net/atlantic: implement firmware operations",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "0a79a2c1b8010efbfca1ae28236d6185dce5b631",
    "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/8e0e8eb1e71d73521b8dc8f272f6fa3cc222df9a.1539338074.git.igor.russkikh@aquantia.com/mbox/",
    "series": [
        {
            "id": 1862,
            "url": "http://patches.dpdk.org/api/series/1862/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=1862",
            "date": "2018-10-12T11:09:01",
            "name": "net/atlantic: Aquantia aQtion 10G NIC Family DPDK PMD driver",
            "version": 6,
            "mbox": "http://patches.dpdk.org/series/1862/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/46700/comments/",
    "check": "success",
    "checks": "http://patches.dpdk.org/api/patches/46700/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 28D0D1B576;\n\tFri, 12 Oct 2018 13:09:21 +0200 (CEST)",
            "from NAM04-BN3-obe.outbound.protection.outlook.com\n\t(mail-eopbgr680088.outbound.protection.outlook.com [40.107.68.88])\n\tby dpdk.org (Postfix) with ESMTP id 8E0181B563\n\tfor <dev@dpdk.org>; Fri, 12 Oct 2018 13:09:17 +0200 (CEST)",
            "from BY1PR0701MB1660.namprd07.prod.outlook.com (10.162.110.22) by\n\tBY1PR0701MB1879.namprd07.prod.outlook.com (10.162.143.149) with\n\tMicrosoft SMTP Server (version=TLS1_2,\n\tcipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id\n\t15.20.1207.26; Fri, 12 Oct 2018 11:09:15 +0000",
            "from BY1PR0701MB1660.namprd07.prod.outlook.com\n\t([fe80::346d:e756:e70e:17]) by\n\tBY1PR0701MB1660.namprd07.prod.outlook.com\n\t([fe80::346d:e756:e70e:17%3]) with mapi id 15.20.1228.020;\n\tFri, 12 Oct 2018 11:09:15 +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=szMguBGLtuimMWmwFwdn6C/Eq6iWcRweXxIkT8Zbacs=;\n\tb=vQ9kHa6Xs6g4n2RJJdhsg4cHBYkt29n6YR1xnKQK6V7qGcKLyl8XXuPlZwtQ8gW8vXJJkmL5T5eVBkfdo5VG0qcQVZVn1o+JPeRCNpIxYPrpGxTmGDIOgo9d32IW8lGZ6QHwFo5zKpqEhQqYt17U9tappj/lFZnpPFWIHXhPjMs=",
        "From": "Igor Russkikh <Igor.Russkikh@aquantia.com>",
        "To": "\"dev@dpdk.org\" <dev@dpdk.org>",
        "CC": "Pavel Belous <Pavel.Belous@aquantia.com>, Igor Russkikh\n\t<Igor.Russkikh@aquantia.com>, \"ferruh.yigit@intel.com\"\n\t<ferruh.yigit@intel.com>",
        "Thread-Topic": "[PATCH v6 05/22] net/atlantic: implement firmware operations",
        "Thread-Index": "AQHUYhwCHs8I+ZIxfUyBtyKDCt3WdA==",
        "Date": "Fri, 12 Oct 2018 11:09:14 +0000",
        "Message-ID": "<8e0e8eb1e71d73521b8dc8f272f6fa3cc222df9a.1539338074.git.igor.russkikh@aquantia.com>",
        "References": "<cover.1539338074.git.igor.russkikh@aquantia.com>",
        "In-Reply-To": "<cover.1539338074.git.igor.russkikh@aquantia.com>",
        "Accept-Language": "en-US",
        "Content-Language": "en-US",
        "X-MS-Has-Attach": "",
        "X-MS-TNEF-Correlator": "",
        "x-clientproxiedby": "AM5PR0701CA0008.eurprd07.prod.outlook.com\n\t(2603:10a6:203:51::18) To BY1PR0701MB1660.namprd07.prod.outlook.com\n\t(2a01:111:e400:522a::22)",
        "authentication-results": "spf=none (sender IP is )\n\tsmtp.mailfrom=Igor.Russkikh@aquantia.com; ",
        "x-ms-exchange-messagesentrepresentingtype": "1",
        "x-originating-ip": "[95.79.108.179]",
        "x-ms-publictraffictype": "Email",
        "x-microsoft-exchange-diagnostics": "1; BY1PR0701MB1879;\n\t6:FERN9mFlVvt1KhK0S86RLmPXTOOK/0vOUHheuo1wNKR0wmff3DpRDC5zWgGRzQl8x9cOO68GpLiEVrSWcRvoucPyTA36Ni1Pp8jqFzTp4Nqel+OwTnFPMIN+CxPWQabKz9Zaqot5n/Rx/lA/Yt6URp0NYKm5gbvIyi0XHPr9IKZs/7PRJI4+6mOLwAAF5MYaVIveoyea/MNPAeNGX6QpnHg+HEVZwYBMIYxU+OT/uWFXODJsWC67wWIvx8gd2TmVSSgXMWAolsxitVgWWbfH4YyfOjmZwjZgjAHd0mfnOE0Axv87Ia3guYG9idQXPJwYU//EX80iuzCiXEHMcCPECv2neyoHFL7DB82ilOubFQwLU4XIb+LJgDEX85/lW3QyFcFbbLRYssfO/y6rSnMyrX9MtP1ZqjDJUlUDKYlsi76cZWtPcHjcNWIyzI35W1/nmrTfXR0kVEtIE348rChIPWszI8emGSuR8RV52uFXoF8=;\n\t5:+wmO8zzK0TkK/gjslLyTr24ymok9siOlpCwtfMffXQNh+dqijgOMZCp4gm8mmTWCe8nU2Z4rJdPzxwaY0UP03w5IkaVmG+NVnWYkBrNFR64EvDpSGrpYbem5aR0n3kAZg+NyiDMITgnZF885S91TIvSRjp7kUZQRXxu6r0J6r8Y=;\n\t7:TnONX9JwGcQ3YAwWcC2fsbUo6ARl0poZrqMiEwJQzddoIbNBYuNEpuwu1N5kLPbdMhoiVUsEe3oytqJQD0Ap0K2QgmssAuV7v81bMeIpa711c3EGRODQ9BAfp/y19Gc1eWDCbymQ4mnoqhEXHRruhMSBXBwWjHmLAsh0Nr5Gx4jULISovnY33bCrGcix5/aTLgYjoMCEV/XrRVv6MdRjZvbSkYCdUxE049samDEj27kJjoSOxUfEChsFN1vyY9QH",
        "x-ms-office365-filtering-correlation-id": "dc95be52-80b9-4ff3-d643-08d6303324bb",
        "x-microsoft-antispam": "BCL:0; PCL:0;\n\tRULEID:(7020095)(4652040)(8989299)(4534185)(4627221)(201703031133081)(201702281549075)(8990200)(5600074)(711020)(2017052603328)(7153060)(7193020);\n\tSRVR:BY1PR0701MB1879; ",
        "x-ms-traffictypediagnostic": "BY1PR0701MB1879:",
        "x-microsoft-antispam-prvs": "<BY1PR0701MB18791D718EACA79FEFC5B5F898E20@BY1PR0701MB1879.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)(10201501046)(3002001)(3231355)(944501410)(52105095)(149066)(150057)(6041310)(20161123558120)(20161123564045)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123562045)(20161123560045)(201708071742011)(7699051)(76991067);\n\tSRVR:BY1PR0701MB1879; BCL:0; PCL:0; RULEID:; SRVR:BY1PR0701MB1879; ",
        "x-forefront-prvs": "0823A5777B",
        "x-forefront-antispam-report": "SFV:NSPM;\n\tSFS:(10009020)(346002)(376002)(366004)(136003)(39850400004)(396003)(189003)(199004)(6436002)(5640700003)(3846002)(68736007)(2900100001)(478600001)(6486002)(14454004)(2906002)(72206003)(71190400001)(71200400001)(26005)(2616005)(44832011)(102836004)(4744004)(446003)(486006)(256004)(118296001)(186003)(105586002)(2351001)(6116002)(106356001)(6512007)(97736004)(6916009)(5660300001)(54906003)(6506007)(386003)(16200700003)(53946003)(11346002)(476003)(14444005)(53936002)(5250100002)(2501003)(25786009)(8936002)(8676002)(4326008)(86362001)(305945005)(7736002)(575784001)(551934003)(99286004)(81166006)(1730700003)(81156014)(66066001)(52116002)(36756003)(316002)(76176011)(569006);\n\tDIR:OUT; SFP:1101; SCL:1; SRVR:BY1PR0701MB1879;\n\tH:BY1PR0701MB1660.namprd07.prod.outlook.com; FPR:; SPF:None; LANG:en; \n\tPTR: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": "GASQDfeyaINxcF3+bUMZPmEniTRfT6dyjx84YFIaZNprQhQ+BXTipywMS1D5Y+eft35aGdn+8uqxOHEO/da88kYWneYRtSHeXnu11PSKNS1bPoqI1qhmPVSEaaiMSiGGgGG5YmzeyCfc/MsJNkUVNxxYOoTfjq8v01YqPAKrO8S2lQxXnvu8Yu2rBQLQ5OI4s1YHxd+U+MCoUQOhI4CX1HM8k0ITLtVDbTooE4CFmtOzNy1FIuLr3/Wl6vW40ge5t3g1E23v+MGv1DfjCIU/rttGsxwAw8QCV9Z7HsUCtS0s8gap73a8gYwClzUiV3BfufR+ONINOJOKd5QltwwUAtdbtT7N3FZ34MgwFNkqG1Q=",
        "spamdiagnosticoutput": "1:99",
        "spamdiagnosticmetadata": "NSPM",
        "Content-Type": "text/plain; charset=\"iso-8859-1\"",
        "Content-Transfer-Encoding": "quoted-printable",
        "MIME-Version": "1.0",
        "X-OriginatorOrg": "aquantia.com",
        "X-MS-Exchange-CrossTenant-Network-Message-Id": "dc95be52-80b9-4ff3-d643-08d6303324bb",
        "X-MS-Exchange-CrossTenant-originalarrivaltime": "12 Oct 2018 11:09:14.8448\n\t(UTC)",
        "X-MS-Exchange-CrossTenant-fromentityheader": "Hosted",
        "X-MS-Exchange-CrossTenant-id": "83e2e134-991c-4ede-8ced-34d47e38e6b1",
        "X-MS-Exchange-Transport-CrossTenantHeadersStamped": "BY1PR0701MB1879",
        "Subject": "[dpdk-dev] [PATCH v6 05/22] net/atlantic: implement firmware\n\toperations",
        "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>\nSigned-off-by: Pavel Belous <pavel.belous@aquantia.com>\n---\n drivers/net/atlantic/Makefile                   |   2 +\n drivers/net/atlantic/atl_types.h                |  95 +++\n drivers/net/atlantic/hw_atl/hw_atl_utils.c      | 942 ++++++++++++++++++++++++\n drivers/net/atlantic/hw_atl/hw_atl_utils.h      | 510 +++++++++++++\n drivers/net/atlantic/hw_atl/hw_atl_utils_fw2x.c | 618 ++++++++++++++++\n drivers/net/atlantic/meson.build                |   2 +\n 6 files changed, 2169 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/Makefile b/drivers/net/atlantic/Makefile\nindex cae317badc0c..a291053b5ab7 100644\n--- a/drivers/net/atlantic/Makefile\n+++ b/drivers/net/atlantic/Makefile\n@@ -26,6 +26,8 @@ VPATH += $(SRCDIR)/hw_atl\n #\n SRCS-$(CONFIG_RTE_LIBRTE_ATLANTIC_PMD) += atl_ethdev.c\n SRCS-$(CONFIG_RTE_LIBRTE_ATLANTIC_PMD) += atl_hw_regs.c\n+SRCS-$(CONFIG_RTE_LIBRTE_ATLANTIC_PMD) += hw_atl_utils.c\n SRCS-$(CONFIG_RTE_LIBRTE_ATLANTIC_PMD) += hw_atl_llh.c\n+SRCS-$(CONFIG_RTE_LIBRTE_ATLANTIC_PMD) += hw_atl_utils_fw2x.c\n \n include $(RTE_SDK)/mk/rte.lib.mk\ndiff --git a/drivers/net/atlantic/atl_types.h b/drivers/net/atlantic/atl_types.h\nindex 725b0c4dc670..af24da3a5a54 100644\n--- a/drivers/net/atlantic/atl_types.h\n+++ b/drivers/net/atlantic/atl_types.h\n@@ -22,8 +22,103 @@ typedef uint64_t\tu64;\n #define min(a, b)\tRTE_MIN(a, b)\n #define max(a, b)\tRTE_MAX(a, b)\n \n+#include \"hw_atl/hw_atl_utils.h\"\n+\n+struct aq_hw_link_status_s {\n+\tunsigned int mbps;\n+};\n+\n+struct aq_stats_s {\n+\tu64 uprc;\n+\tu64 mprc;\n+\tu64 bprc;\n+\tu64 erpt;\n+\tu64 uptc;\n+\tu64 mptc;\n+\tu64 bptc;\n+\tu64 erpr;\n+\tu64 mbtc;\n+\tu64 bbtc;\n+\tu64 mbrc;\n+\tu64 bbrc;\n+\tu64 ubrc;\n+\tu64 ubtc;\n+\tu64 dpc;\n+\tu64 dma_pkt_rc;\n+\tu64 dma_pkt_tc;\n+\tu64 dma_oct_rc;\n+\tu64 dma_oct_tc;\n+};\n+\n+struct aq_hw_cfg_s {\n+\tbool is_lro;\n+\tint wol;\n+\n+\tint link_speed_msk;\n+\tint irq_type;\n+\tint irq_mask;\n+\tunsigned int vecs;\n+\n+\tuint32_t flow_control;\n+};\n+\n struct aq_hw_s {\n+\tu8 rbl_enabled:1;\n+\tstruct aq_hw_cfg_s *aq_nic_cfg;\n+\tconst struct aq_fw_ops *aq_fw_ops;\n \tvoid *mmio;\n+\n+\tstruct aq_hw_link_status_s aq_link_status;\n+\n+\tstruct hw_aq_atl_utils_mbox mbox;\n+\tstruct hw_atl_stats_s last_stats;\n+\tstruct aq_stats_s curr_stats;\n+\n+\tunsigned int chip_features;\n+\tu32 fw_ver_actual;\n+\tu32 mbox_addr;\n+\tu32 rpc_addr;\n+\tu32 rpc_tid;\n+\tstruct hw_aq_atl_utils_fw_rpc rpc;\n+};\n+\n+struct aq_fw_ops {\n+\tint (*init)(struct aq_hw_s *self);\n+\n+\tint (*deinit)(struct aq_hw_s *self);\n+\n+\tint (*reset)(struct aq_hw_s *self);\n+\n+\tint (*get_mac_permanent)(struct aq_hw_s *self, u8 *mac);\n+\n+\tint (*set_link_speed)(struct aq_hw_s *self, u32 speed);\n+\n+\tint (*set_state)(struct aq_hw_s *self,\n+\t\t\tenum hal_atl_utils_fw_state_e state);\n+\n+\tint (*update_link_status)(struct aq_hw_s *self);\n+\n+\tint (*update_stats)(struct aq_hw_s *self);\n+\n+\tint (*set_power)(struct aq_hw_s *self, unsigned int power_state,\n+\t\t\tu8 *mac);\n+\n+\tint (*get_temp)(struct aq_hw_s *self, int *temp);\n+\n+\tint (*get_cable_len)(struct aq_hw_s *self, int *cable_len);\n+\n+\tint (*set_eee_rate)(struct aq_hw_s *self, u32 speed);\n+\n+\tint (*get_eee_rate)(struct aq_hw_s *self, u32 *rate,\n+\t\t\tu32 *supported_rates);\n+\n+\tint (*set_flow_control)(struct aq_hw_s *self);\n+\n+\tint (*led_control)(struct aq_hw_s *self, u32 mode);\n+\n+\tint (*get_eeprom)(struct aq_hw_s *self, u32 *data, u32 len);\n+\n+\tint (*set_eeprom)(struct aq_hw_s *self, u32 *data, u32 len);\n };\n \n #endif\ndiff --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 000000000000..f11093a50404\n--- /dev/null\n+++ b/drivers/net/atlantic/hw_atl/hw_atl_utils.c\n@@ -0,0 +1,942 @@\n+// SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0)\n+/* Copyright (C) 2014-2017 aQuantia Corporation. */\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+static 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 = -ETIMEDOUT;\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 = -ETIMEDOUT;\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\thw_atl_mcp_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;\n+\t\tpmbox->stats.ubrc = pmbox->stats.uprc * mtu;\n+\t\tpmbox->stats.ubtc = pmbox->stats.uptc * mtu;\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,\n+\t\t\t(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 =\n+\t   hw_atl_stats_rx_dma_good_pkt_counterlsw_get(self) +\n+\t   ((u64)hw_atl_stats_rx_dma_good_pkt_countermsw_get(self) << 32);\n+\tself->curr_stats.dma_pkt_tc =\n+\t   hw_atl_stats_tx_dma_good_pkt_counterlsw_get(self) +\n+\t   ((u64)hw_atl_stats_tx_dma_good_pkt_countermsw_get(self) << 32);\n+\tself->curr_stats.dma_oct_rc =\n+\t   hw_atl_stats_rx_dma_good_octet_counterlsw_get(self) +\n+\t   ((u64)hw_atl_stats_rx_dma_good_octet_countermsw_get(self) << 32);\n+\tself->curr_stats.dma_oct_tc =\n+\t   hw_atl_stats_tx_dma_good_octet_counterlsw_get(self) +\n+\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\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,\n+\t\t\t(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,\n+\t\t      unsigned int power_state __rte_unused,\n+\t\t      u8 *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 000000000000..5f3f70847310\n--- /dev/null\n+++ b/drivers/net/atlantic/hw_atl/hw_atl_utils.h\n@@ -0,0 +1,510 @@\n+/* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0) */\n+/* Copyright (C) 2014-2017 aQuantia Corporation. */\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+\tu64 buf_addr;\n+\n+\tunion {\n+\t\tstruct {\n+\t\t\tu32 type:3;\n+\t\t\tu32:1;\n+\t\t\tu32 len:16;\n+\t\t\tu32 dd:1;\n+\t\t\tu32 eop:1;\n+\t\t\tu32 cmd:8;\n+\t\t\tu32:14;\n+\t\t\tu32 ct_idx:1;\n+\t\t\tu32 ct_en:1;\n+\t\t\tu32 pay_len:18;\n+\t\t} __attribute__((__packed__));\n+\t\tu64 flags;\n+\t};\n+} __attribute__((__packed__));\n+\n+/* Hardware tx context descriptor */\n+union hw_atl_txc_s {\n+\tstruct {\n+\t\tu64 flags1;\n+\t\tu64 flags2;\n+\t};\n+\n+\tstruct {\n+\t\tu64:40;\n+\t\tu32 tun_len:8;\n+\t\tu32 out_len:16;\n+\t\tu32 type:3;\n+\t\tu32 idx:1;\n+\t\tu32 vlan_tag:16;\n+\t\tu32 cmd:4;\n+\t\tu32 l2_len:7;\n+\t\tu32 l3_len:9;\n+\t\tu32 l4_len:8;\n+\t\tu32 mss_len:16;\n+\t} __attribute__((__packed__));\n+} __attribute__((__packed__));\n+\n+enum aq_tx_desc_type {\n+\ttx_desc_type_desc = 1,\n+\ttx_desc_type_ctx = 2,\n+};\n+\n+enum aq_tx_desc_cmd {\n+\ttx_desc_cmd_vlan = 1,\n+\ttx_desc_cmd_fcs = 2,\n+\ttx_desc_cmd_ipv4 = 4,\n+\ttx_desc_cmd_l4cs = 8,\n+\ttx_desc_cmd_lso = 0x10,\n+\ttx_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 tc_quanta[8];\n+\t\t\tu16 tc_threshold[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 000000000000..6841d9bce39c\n--- /dev/null\n+++ b/drivers/net/atlantic/hw_atl/hw_atl_utils_fw2x.c\n@@ -0,0 +1,618 @@\n+// SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0)\n+/* Copyright (C) 2014-2017 aQuantia Corporation. */\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\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,\n+\t\t\t(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,\n+\t\t\t     unsigned int power_state __rte_unused,\n+\t\t\t     u8 *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 (self->fw_ver_actual < HW_ATL_FW_FEATURE_LED)\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 (self->fw_ver_actual < HW_ATL_FW_FEATURE_EEPROM)\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),\n+\t\t10U, 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,\n+\t\t\t\tself->rpc_addr + sizeof(u32) * 2,\n+\t\t\t\tdata,\n+\t\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 (self->fw_ver_actual < HW_ATL_FW_FEATURE_EEPROM)\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,\n+\t\t\t\tself->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),\n+\t\t10U, 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+};\ndiff --git a/drivers/net/atlantic/meson.build b/drivers/net/atlantic/meson.build\nindex 055342ec9db7..b05c97773541 100644\n--- a/drivers/net/atlantic/meson.build\n+++ b/drivers/net/atlantic/meson.build\n@@ -5,4 +5,6 @@ sources = files(\n \t'atl_ethdev.c',\n \t'atl_hw_regs.c',\n \t'hw_atl/hw_atl_llh.c',\n+\t'hw_atl/hw_atl_utils_fw2x.c',\n+\t'hw_atl/hw_atl_utils.c',\n )\n",
    "prefixes": [
        "v6",
        "05/22"
    ]
}