get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 2229626,
    "url": "http://patchwork.ozlabs.org/api/1.1/patches/2229626/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/uboot/patch/20260428-add-ethernet-support-for-genio-520-720-v2-5-9cf2f0884bd8@baylibre.com/",
    "project": {
        "id": 18,
        "url": "http://patchwork.ozlabs.org/api/1.1/projects/18/?format=api",
        "name": "U-Boot",
        "link_name": "uboot",
        "list_id": "u-boot.lists.denx.de",
        "list_email": "u-boot@lists.denx.de",
        "web_url": null,
        "scm_url": null,
        "webscm_url": null
    },
    "msgid": "<20260428-add-ethernet-support-for-genio-520-720-v2-5-9cf2f0884bd8@baylibre.com>",
    "date": "2026-04-28T13:17:12",
    "name": "[v2,5/9] net: phy: air_phy_lib: Factorize BuckPBus register",
    "commit_ref": null,
    "pull_url": null,
    "state": "new",
    "archived": false,
    "hash": "921218a42ed02fc211bf946a95d66dd818068b42",
    "submitter": {
        "id": 84831,
        "url": "http://patchwork.ozlabs.org/api/1.1/people/84831/?format=api",
        "name": "Julien Stephan",
        "email": "jstephan@baylibre.com"
    },
    "delegate": {
        "id": 161331,
        "url": "http://patchwork.ozlabs.org/api/1.1/users/161331/?format=api",
        "username": "dlech",
        "first_name": "David",
        "last_name": "Lechner",
        "email": "dlechner@baylibre.com"
    },
    "mbox": "http://patchwork.ozlabs.org/project/uboot/patch/20260428-add-ethernet-support-for-genio-520-720-v2-5-9cf2f0884bd8@baylibre.com/mbox/",
    "series": [
        {
            "id": 501871,
            "url": "http://patchwork.ozlabs.org/api/1.1/series/501871/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/uboot/list/?series=501871",
            "date": "2026-04-28T13:17:07",
            "name": "Add ethernet support for genio 520/720 EVK boards",
            "version": 2,
            "mbox": "http://patchwork.ozlabs.org/series/501871/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/2229626/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/2229626/checks/",
    "tags": {},
    "headers": {
        "Return-Path": "<u-boot-bounces@lists.denx.de>",
        "X-Original-To": "incoming@patchwork.ozlabs.org",
        "Delivered-To": "patchwork-incoming@legolas.ozlabs.org",
        "Authentication-Results": [
            "legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=baylibre-com.20251104.gappssmtp.com\n header.i=@baylibre-com.20251104.gappssmtp.com header.a=rsa-sha256\n header.s=20251104 header.b=cPygaKoK;\n\tdkim-atps=neutral",
            "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de\n (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de;\n envelope-from=u-boot-bounces@lists.denx.de; receiver=patchwork.ozlabs.org)",
            "phobos.denx.de;\n dmarc=none (p=none dis=none) header.from=baylibre.com",
            "phobos.denx.de;\n spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de",
            "phobos.denx.de;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=baylibre-com.20251104.gappssmtp.com\n header.i=@baylibre-com.20251104.gappssmtp.com header.b=\"cPygaKoK\";\n\tdkim-atps=neutral",
            "phobos.denx.de;\n dmarc=none (p=none dis=none) header.from=baylibre.com",
            "phobos.denx.de;\n spf=pass smtp.mailfrom=jstephan@baylibre.com"
        ],
        "Received": [
            "from phobos.denx.de (phobos.denx.de\n [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4g4kDP5Nczz1xvV\n\tfor <incoming@patchwork.ozlabs.org>; Wed, 29 Apr 2026 01:01:57 +1000 (AEST)",
            "from h2850616.stratoserver.net (localhost [IPv6:::1])\n\tby phobos.denx.de (Postfix) with ESMTP id 6F04784612;\n\tTue, 28 Apr 2026 17:00:45 +0200 (CEST)",
            "by phobos.denx.de (Postfix, from userid 109)\n id BF513842A2; Tue, 28 Apr 2026 15:17:39 +0200 (CEST)",
            "from mail-wm1-x32f.google.com (mail-wm1-x32f.google.com\n [IPv6:2a00:1450:4864:20::32f])\n (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits))\n (No client certificate requested)\n by phobos.denx.de (Postfix) with ESMTPS id 20A7984119\n for <u-boot@lists.denx.de>; Tue, 28 Apr 2026 15:17:36 +0200 (CEST)",
            "by mail-wm1-x32f.google.com with SMTP id\n 5b1f17b1804b1-488b0046078so103303515e9.1\n for <u-boot@lists.denx.de>; Tue, 28 Apr 2026 06:17:36 -0700 (PDT)",
            "from [192.168.1.100]\n (2a02-842a-d52e-6101-1bf9-06eb-939c-90d1.rev.sfr.net.\n [2a02:842a:d52e:6101:1bf9:6eb:939c:90d1])\n by smtp.gmail.com with ESMTPSA id\n ffacd0b85a97d-4463d5ee9ecsm7139599f8f.16.2026.04.28.06.17.31\n (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n Tue, 28 Apr 2026 06:17:33 -0700 (PDT)"
        ],
        "X-Spam-Checker-Version": "SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de",
        "X-Spam-Level": "",
        "X-Spam-Status": "No, score=-1.9 required=5.0 tests=BAYES_00,DKIM_SIGNED,\n DKIM_VALID,RCVD_IN_DNSWL_BLOCKED,SPF_HELO_NONE,SPF_PASS autolearn=ham\n autolearn_force=no version=3.4.2",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=baylibre-com.20251104.gappssmtp.com; s=20251104; t=1777382255;\n x=1777987055;\n darn=lists.denx.de;\n h=cc:to:in-reply-to:references:message-id:content-transfer-encoding\n :mime-version:subject:date:from:from:to:cc:subject:date:message-id\n :reply-to; bh=ElLrpfQpnFx5Wib6J70tj8vI5/5+gFsJiTFxMkUQNxw=;\n b=cPygaKoKLlz2VZcnLbYPpe7d9X6hUGRgZdw52CXX87YO+zvcoE65ibuN2Z9IN6Q/XZ\n paGXZVpIcvC8V3Q2/Hbbbsy3rc8NaRSasAfBFJW30IDJhr0fDcdEcwdroTNHqp+IWfo0\n Db5/8Ar2Y6jDyEAY1+4vEb/AmI3AgBUu1j2Dfku4eM37K0rH83o+FhZMSychQwdRmpp9\n vQ+sS2HL0Cz/act1HLLFf8qpKUwGYP6qemrP5v5U7A4tZtqQLBedHyM07SRyzzJn4WU7\n ofZVTYq0ZLX44J8MZfTPg5xMdseqdUQTXB83ub84aT4swlu7CR+J1CGKsx6Xu6lq3272\n TepQ==",
        "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20251104; t=1777382255; x=1777987055;\n h=cc:to:in-reply-to:references:message-id:content-transfer-encoding\n :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to\n :cc:subject:date:message-id:reply-to;\n bh=ElLrpfQpnFx5Wib6J70tj8vI5/5+gFsJiTFxMkUQNxw=;\n b=IT1BqOTTniulP4/g/ISdQ4Ti440O8pkZHOyeHEYUbuoJRnGD41KhOUCCNxjbMpHHCH\n 7Y2qVEgX/w0hO74sEe0Lh1vrq8LPRfttugMarXiedr6uqMq0xvGN02QYtLb5t0lga+zd\n aYuG7GQI4pfcn6VWDiO9GCuVCCi023u1JtYjjVNvDpiAriWnsuDZsMFU+iQKJRUB9LJj\n MjuLOhWBBk+pNCJitZLGKTxu0TTx7NF3sf/tE1J//JqeLz0i532vX2meGbF9r8R/29JF\n Z55F/2VDaomvU///TMy87u1Q+o6e9Ag4SpqvOVY8yANaNW0j3imr/F94bZcFtn0aGvMF\n 8/Gw==",
        "X-Gm-Message-State": "AOJu0Yywz0Hces+lQUsmjTZQuxPJOFQMqyPeP2wwiIXDp3R9+7avfbBf\n KwQpYlGUHciBLixzZPiJhNaLv+6osHVaZZlo2QmLqHRyjH8AGhotmol44ImCvf1hcwc=",
        "X-Gm-Gg": "AeBDiev8uESRtUdS2hzUWvlipWNw18SJhx9icqsVZFop++JAjhj/9BCTTbDZEA+/zWm\n QB/sFkBsmzTmSJA81C8Bmjyn02gxKpAsPBlIix0moIDPZgy6RCjFdWmvgmVbBP7x85LyMZh5aKQ\n bVNtzFq3LTWfJhoI18ImT4EpnmU0ZdR4YSukgas/CUrzUIjChRUN0IR1Imy1ZRQFjFJJo48RGOD\n cABaSuSqnGTfmyafqXt3tfCWTUnPV09uapUtFFY1NA+mxCpoATkQThD5z6CjHRL5x+uJbQ7JFed\n daXR7OlnBcY42xAEm2xpt6cmkH2Hi2jSdLv8aq1iXia5B8vlCIBLbb1Ac3VZuQbPGKrRFyfTU5N\n r/YLQXsnxJWk+LG9BxDHIzF45NYb0aeWUD2YfBAmOg3eYlOEI1ocnLfZaZjiywLgEX7CdqV89iD\n UnB2OinUBALIr8DzQEL+yleeT2ozZL0/ApBlAS9ydFiM5guJ+pPD4uJJ5jtTYb4nW3h3+ZXb5KZ\n WnO/Z6A+urLDZ4mB8bCgE0d0brcCAxX0ACvuJHA+rwq6w9ZCmTy2jUqrBagqs5ytBmQ+clSbW4H\n AS+2oAr8EDZ7UDxNHA==",
        "X-Received": "by 2002:a05:600d:8402:b0:489:149a:f9e7 with SMTP id\n 5b1f17b1804b1-48a77b25340mr39756365e9.27.1777382255282;\n Tue, 28 Apr 2026 06:17:35 -0700 (PDT)",
        "From": "Julien Stephan <jstephan@baylibre.com>",
        "Date": "Tue, 28 Apr 2026 15:17:12 +0200",
        "Subject": "[PATCH v2 5/9] net: phy: air_phy_lib: Factorize BuckPBus register",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain; charset=\"utf-8\"",
        "Content-Transfer-Encoding": "7bit",
        "Message-Id": "\n <20260428-add-ethernet-support-for-genio-520-720-v2-5-9cf2f0884bd8@baylibre.com>",
        "References": "\n <20260428-add-ethernet-support-for-genio-520-720-v2-0-9cf2f0884bd8@baylibre.com>",
        "In-Reply-To": "\n <20260428-add-ethernet-support-for-genio-520-720-v2-0-9cf2f0884bd8@baylibre.com>",
        "To": "u-boot@lists.denx.de",
        "Cc": "GSS_MTK_Uboot_upstream <GSS_MTK_Uboot_upstream@mediatek.com>,\n Jerome Forissier <jerome.forissier@arm.com>, Tom Rini <trini@konsulko.com>,\n Christian Marangi <ansuelsmth@gmail.com>,\n Robert Marko <robert.marko@sartura.hr>, Simon Glass <sjg@chromium.org>,\n Yao Zi <me@ziyao.cc>, Quentin Schulz <quentin.schulz@cherry.de>,\n Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>,\n Marek Vasut <marek.vasut+renesas@mailbox.org>,\n \"Lucien.Jheng\" <lucienzx159@gmail.com>,\n Weijie Gao <weijie.gao@mediatek.com>,\n Romain Gantois <romain.gantois@bootlin.com>,\n Siddharth Vadapalli <s-vadapalli@ti.com>,\n Yanqing Wang <ot_yanqing.wang@mediatek.com>, Beiyan Yun <root@infi.wang>,\n Ryder Lee <ryder.lee@mediatek.com>,\n Chunfeng Yun <chunfeng.yun@mediatek.com>,\n Igor Belwon <igor.belwon@mentallysanemainliners.org>,\n David Lechner <dlechner@baylibre.com>,\n Neil Armstrong <neil.armstrong@linaro.org>,\n Kory Maincent <kory.maincent@bootlin.com>,\n Ilias Apalodimas <ilias.apalodimas@linaro.org>,\n Kuan-Wei Chiu <visitorckw@gmail.com>,\n Raymond Mao <raymond.mao@riscstar.com>, Peng Fan <peng.fan@nxp.com>,\n Stefan Roese <stefan.roese@mailbox.org>,\n Philip Molloy <philip.molloy@analog.com>,\n fanyi zhang <fanyi.zhang@mediatek.com>, Jonas Karlman <jonas@kwiboo.se>,\n Kever Yang <kever.yang@rock-chips.com>,\n Marek Vasut <marek.vasut@mailbox.org>,\n Patrick Delaunay <patrick.delaunay@foss.st.com>,\n Heiko Stuebner <heiko@sntech.de>,\n Samuel Holland <samuel.holland@sifive.com>,\n Christophe Roullier <christophe.roullier@foss.st.com>,\n Patrice Chotard <patrice.chotard@foss.st.com>,\n Chris-QJ Chen <chris-qj.chen@mediatek.com>,\n Macpaul Lin <macpaul.lin@mediatek.com>,\n Sam Protsenko <semen.protsenko@linaro.org>,\n Michael Trimarchi <michael@amarulasolutions.com>,\n Sky Huang <SkyLake.Huang@mediatek.com>,\n Leo Yu-Chi Liang <ycliang@andestech.com>,\n Tommy Shih <tommy.shih@airoha.com>,\n Kevin-KW Huang <kevin-kw.huang@airoha.com>,\n Julien Stephan <jstephan@baylibre.com>",
        "X-Mailer": "b4 0.14.3",
        "X-Mailman-Approved-At": "Tue, 28 Apr 2026 17:00:38 +0200",
        "X-BeenThere": "u-boot@lists.denx.de",
        "X-Mailman-Version": "2.1.39",
        "Precedence": "list",
        "List-Id": "U-Boot discussion <u-boot.lists.denx.de>",
        "List-Unsubscribe": "<https://lists.denx.de/options/u-boot>,\n <mailto:u-boot-request@lists.denx.de?subject=unsubscribe>",
        "List-Archive": "<https://lists.denx.de/pipermail/u-boot/>",
        "List-Post": "<mailto:u-boot@lists.denx.de>",
        "List-Help": "<mailto:u-boot-request@lists.denx.de?subject=help>",
        "List-Subscribe": "<https://lists.denx.de/listinfo/u-boot>,\n <mailto:u-boot-request@lists.denx.de?subject=subscribe>",
        "Errors-To": "u-boot-bounces@lists.denx.de",
        "Sender": "\"U-Boot\" <u-boot-bounces@lists.denx.de>",
        "X-Virus-Scanned": "clamav-milter 0.103.8 at phobos.denx.de",
        "X-Virus-Status": "Clean"
    },
    "content": "In preparation of Airoha AN8801R PHY support, move the BuckPBus\nregister accessors and definitions, present in air_en8811h driver,\ninto the Airoha PHY shared code (air_phy_lib), so they will be usable\nby the new driver without duplicating them.\nAlso, update air_en8811h driver to use the new function names.\n\nAdapted from [1].\n\n[1]: https://lore.kernel.org/all/20260326-add-airoha-an8801-support-v2-2-1a42d6b6050f@collabora.com/\n\nSigned-off-by: Julien Stephan <jstephan@baylibre.com>\n---\n MAINTAINERS                          |   2 +-\n drivers/net/phy/airoha/Kconfig       |   6 +\n drivers/net/phy/airoha/Makefile      |   1 +\n drivers/net/phy/airoha/air_en8811.c  | 304 ++++++++---------------------------\n drivers/net/phy/airoha/air_phy_lib.c | 216 +++++++++++++++++++++++++\n drivers/net/phy/airoha/air_phy_lib.h |  39 +++++\n 6 files changed, 329 insertions(+), 239 deletions(-)",
    "diff": "diff --git a/MAINTAINERS b/MAINTAINERS\nindex 40ba3542ca3..4bda6b9e8c4 100644\n--- a/MAINTAINERS\n+++ b/MAINTAINERS\n@@ -61,7 +61,7 @@ F:\tlib/acpi/\n AIROHA PHY\n M:\tTommy Shih <tommy.shih@airoha.com>\n S:\tMaintained\n-F:\tdrivers/net/phy/airoha/air_en8811.c\n+F:\tdrivers/net/phy/airoha/\n \n ALIST\n M:\tSimon Glass <sjg@chromium.org>\ndiff --git a/drivers/net/phy/airoha/Kconfig b/drivers/net/phy/airoha/Kconfig\nindex da8747939e3..2a2f4f05bb2 100644\n--- a/drivers/net/phy/airoha/Kconfig\n+++ b/drivers/net/phy/airoha/Kconfig\n@@ -7,6 +7,12 @@ config PHY_AIROHA_EN8811\n \tdepends on PHY_AIROHA\n \tdepends on SUPPORTS_FW_LOADER\n \tselect FW_LOADER\n+\tselect PHY_AIRONA_PHYLIB\n \thelp\n \t  AIROHA EN8811H supported.\n \t  AIROHA AN8811HB supported.\n+\n+config PHY_AIRONA_PHYLIB\n+\ttristate\n+\thelp\n+\t  Airoha Ethernet PHY common library\ndiff --git a/drivers/net/phy/airoha/Makefile b/drivers/net/phy/airoha/Makefile\nindex 84d23b19ab0..cbf123986f2 100644\n--- a/drivers/net/phy/airoha/Makefile\n+++ b/drivers/net/phy/airoha/Makefile\n@@ -1,3 +1,4 @@\n # SPDX-License-Identifier: GPL-2.0\n \n obj-$(CONFIG_PHY_AIROHA_EN8811) += air_en8811.o\n+obj-$(CONFIG_PHY_AIRONA_PHYLIB) += air_phy_lib.o\ndiff --git a/drivers/net/phy/airoha/air_en8811.c b/drivers/net/phy/airoha/air_en8811.c\nindex 0b974472732..de7542eb079 100644\n--- a/drivers/net/phy/airoha/air_en8811.c\n+++ b/drivers/net/phy/airoha/air_en8811.c\n@@ -24,6 +24,8 @@\n #include <dm/device_compat.h>\n #include <u-boot/crc.h>\n \n+#include \"air_phy_lib.h\"\n+\n /* MII Registers */\n #define AIR_AUX_CTRL_STATUS\t\t0x1d\n #define AIR_AUX_CTRL_STATUS_SPEED_MASK\tGENMASK(4, 2)\n@@ -32,10 +34,6 @@\n #define AIR_AUX_CTRL_STATUS_SPEED_1000\t0x8\n #define AIR_AUX_CTRL_STATUS_SPEED_2500\t0xc\n \n-#define AIR_EXT_PAGE_ACCESS\t\t0x1f\n-#define AIR_PHY_PAGE_STANDARD\t\t0x0000\n-#define AIR_PHY_PAGE_EXTENDED_4\t\t0x0004\n-\n #define AIR_PBUS_MODE_ADDR_HIGH\t\t0x1c\n /* MII Registers Page 4 */\n #define AIR_BPBUS_MODE\t\t\t0x10\n@@ -309,166 +307,6 @@ static int air_pbus_reg_write(struct phy_device *phydev,\n \treturn ret;\n }\n \n-static int air_buckpbus_reg_write(struct phy_device *phydev,\n-\t\t\t\t  u32 pbus_address, u32 pbus_data)\n-{\n-\tint ret, saved_page;\n-\n-\tsaved_page = phy_select_page(phydev, AIR_PHY_PAGE_EXTENDED_4);\n-\tif (saved_page < 0)\n-\t\treturn saved_page;\n-\n-\tret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_MODE,\n-\t\t\tAIR_BPBUS_MODE_ADDR_FIXED);\n-\tif (ret < 0)\n-\t\tgoto restore_page;\n-\n-\tret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_WR_ADDR_HIGH,\n-\t\t\tupper_16_bits(pbus_address));\n-\tif (ret < 0)\n-\t\tgoto restore_page;\n-\n-\tret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_WR_ADDR_LOW,\n-\t\t\tlower_16_bits(pbus_address));\n-\tif (ret < 0)\n-\t\tgoto restore_page;\n-\n-\tret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_WR_DATA_HIGH,\n-\t\t\tupper_16_bits(pbus_data));\n-\tif (ret < 0)\n-\t\tgoto restore_page;\n-\n-\tret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_WR_DATA_LOW,\n-\t\t\tlower_16_bits(pbus_data));\n-\tif (ret < 0)\n-\t\tgoto restore_page;\n-\n-restore_page:\n-\tif (ret < 0)\n-\t\tdev_err(phydev->dev, \"%s 0x%08x failed: %d\\n\", __func__,\n-\t\t\tpbus_address, ret);\n-\n-\treturn phy_restore_page(phydev, saved_page, ret);\n-}\n-\n-static int air_buckpbus_reg_read(struct phy_device *phydev,\n-\t\t\t\t u32 pbus_address, u32 *pbus_data)\n-{\n-\tint pbus_data_low, pbus_data_high;\n-\tint ret = 0, saved_page;\n-\n-\tsaved_page = phy_select_page(phydev, AIR_PHY_PAGE_EXTENDED_4);\n-\tif (saved_page < 0)\n-\t\treturn saved_page;\n-\n-\tret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_MODE,\n-\t\t\tAIR_BPBUS_MODE_ADDR_FIXED);\n-\tif (ret < 0)\n-\t\tgoto restore_page;\n-\n-\tret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_RD_ADDR_HIGH,\n-\t\t\tupper_16_bits(pbus_address));\n-\tif (ret < 0)\n-\t\tgoto restore_page;\n-\n-\tret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_RD_ADDR_LOW,\n-\t\t\tlower_16_bits(pbus_address));\n-\tif (ret < 0)\n-\t\tgoto restore_page;\n-\n-\tpbus_data_high = phy_read(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_RD_DATA_HIGH);\n-\tif (pbus_data_high < 0) {\n-\t\tret = pbus_data_high;\n-\t\tgoto restore_page;\n-\t}\n-\n-\tpbus_data_low = phy_read(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_RD_DATA_LOW);\n-\tif (pbus_data_low < 0) {\n-\t\tret = pbus_data_low;\n-\t\tgoto restore_page;\n-\t}\n-\n-\t*pbus_data = pbus_data_low | (pbus_data_high << 16);\n-\n-restore_page:\n-\tif (ret < 0)\n-\t\tdev_err(phydev->dev, \"%s 0x%08x failed: %d\\n\", __func__,\n-\t\t\tpbus_address, ret);\n-\n-\treturn phy_restore_page(phydev, saved_page, ret);\n-}\n-\n-static int air_buckpbus_reg_modify(struct phy_device *phydev,\n-\t\t\t\t   u32 pbus_address, u32 mask, u32 set)\n-{\n-\tint pbus_data_low, pbus_data_high;\n-\tu32 pbus_data_old, pbus_data_new;\n-\tint ret = 0, saved_page;\n-\n-\tsaved_page = phy_select_page(phydev, AIR_PHY_PAGE_EXTENDED_4);\n-\tif (saved_page < 0)\n-\t\treturn saved_page;\n-\n-\tret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_MODE,\n-\t\t\tAIR_BPBUS_MODE_ADDR_FIXED);\n-\tif (ret < 0)\n-\t\tgoto restore_page;\n-\n-\tret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_RD_ADDR_HIGH,\n-\t\t\tupper_16_bits(pbus_address));\n-\tif (ret < 0)\n-\t\tgoto restore_page;\n-\n-\tret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_RD_ADDR_LOW,\n-\t\t\tlower_16_bits(pbus_address));\n-\tif (ret < 0)\n-\t\tgoto restore_page;\n-\n-\tpbus_data_high = phy_read(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_RD_DATA_HIGH);\n-\tif (pbus_data_high < 0) {\n-\t\tret = pbus_data_high;\n-\t\tgoto restore_page;\n-\t}\n-\n-\tpbus_data_low = phy_read(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_RD_DATA_LOW);\n-\tif (pbus_data_low < 0) {\n-\t\tret = pbus_data_low;\n-\t\tgoto restore_page;\n-\t}\n-\n-\tpbus_data_old = pbus_data_low | (pbus_data_high << 16);\n-\tpbus_data_new = (pbus_data_old & ~mask) | set;\n-\tif (pbus_data_new == pbus_data_old)\n-\t\tgoto restore_page;\n-\n-\tret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_WR_ADDR_HIGH,\n-\t\t\tupper_16_bits(pbus_address));\n-\tif (ret < 0)\n-\t\tgoto restore_page;\n-\n-\tret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_WR_ADDR_LOW,\n-\t\t\tlower_16_bits(pbus_address));\n-\tif (ret < 0)\n-\t\tgoto restore_page;\n-\n-\tret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_WR_DATA_HIGH,\n-\t\t\tupper_16_bits(pbus_data_new));\n-\tif (ret < 0)\n-\t\tgoto restore_page;\n-\n-\tret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_WR_DATA_LOW,\n-\t\t\tlower_16_bits(pbus_data_new));\n-\tif (ret < 0)\n-\t\tgoto restore_page;\n-\n-restore_page:\n-\tif (ret < 0)\n-\t\tdev_err(phydev->dev, \"%s 0x%08x failed: %d\\n\", __func__,\n-\t\t\tpbus_address, ret);\n-\n-\treturn phy_restore_page(phydev, saved_page, ret);\n-}\n-\n static int air_write_buf(struct phy_device *phydev, unsigned long address,\n \t\t\t unsigned long array_size, const unsigned char *buffer)\n {\n@@ -539,12 +377,12 @@ static int an8811hb_check_crc(struct phy_device *phydev,\n \tu32 pbus_value;\n \n \t/* Configure CRC */\n-\tret = air_buckpbus_reg_modify(phydev, set1, AN8811HB_CRC_RD_EN,\n-\t\t\t\t      AN8811HB_CRC_RD_EN);\n+\tret = air_phy_buckpbus_reg_modify(phydev, set1, AN8811HB_CRC_RD_EN,\n+\t\t\t\t\t  AN8811HB_CRC_RD_EN);\n \tif (ret < 0)\n \t\treturn ret;\n \n-\tret = air_buckpbus_reg_read(phydev, set1, &pbus_value);\n+\tret = air_phy_buckpbus_reg_read(phydev, set1, &pbus_value);\n \tif (ret < 0)\n \t\treturn ret;\n \n@@ -553,14 +391,14 @@ static int an8811hb_check_crc(struct phy_device *phydev,\n \tdo {\n \t\tmdelay(300);\n \n-\t\tret = air_buckpbus_reg_read(phydev, mon2, &pbus_value);\n+\t\tret = air_phy_buckpbus_reg_read(phydev, mon2, &pbus_value);\n \t\tif (ret < 0)\n \t\t\treturn ret;\n \n \t\tdebug(\"%d: reg 0x%x val 0x%x!\\n\", __LINE__, mon2, pbus_value);\n \n \t\tif (pbus_value & AN8811HB_CRC_ST) {\n-\t\t\tret = air_buckpbus_reg_read(phydev, mon3, &pbus_value);\n+\t\t\tret = air_phy_buckpbus_reg_read(phydev, mon3, &pbus_value);\n \t\t\tif (ret < 0)\n \t\t\t\treturn ret;\n \n@@ -584,11 +422,11 @@ static int an8811hb_check_crc(struct phy_device *phydev,\n \t\t}\n \t} while (--retry);\n \n-\tret = air_buckpbus_reg_modify(phydev, set1, AN8811HB_CRC_RD_EN, 0);\n+\tret = air_phy_buckpbus_reg_modify(phydev, set1, AN8811HB_CRC_RD_EN, 0);\n \tif (ret < 0)\n \t\treturn ret;\n \n-\tret = air_buckpbus_reg_read(phydev, set1, &pbus_value);\n+\tret = air_phy_buckpbus_reg_read(phydev, set1, &pbus_value);\n \tif (ret < 0)\n \t\treturn ret;\n \n@@ -646,9 +484,9 @@ static int an8811hb_surge_protect_cfg(struct phy_device *phydev)\n \t\treturn ret;\n \t}\n \n-\tret = air_buckpbus_reg_modify(phydev, AIR_PHY_CONTROL,\n-\t\t\t\t      AIR_PHY_CONTROL_SURGE_5R,\n-\t\t\t\t      AIR_PHY_CONTROL_SURGE_5R);\n+\tret = air_phy_buckpbus_reg_modify(phydev, AIR_PHY_CONTROL,\n+\t\t\t\t\t  AIR_PHY_CONTROL_SURGE_5R,\n+\t\t\t\t\t  AIR_PHY_CONTROL_SURGE_5R);\n \tif (ret < 0)\n \t\treturn ret;\n \n@@ -706,14 +544,14 @@ static int en8811h_load_firmware(struct phy_device *phydev)\n \t\tgoto en8811h_load_firmware_out;\n \t}\n \n-\tret = air_buckpbus_reg_write(phydev, EN8811H_FW_CTRL_1,\n-\t\t\t\t     EN8811H_FW_CTRL_1_START);\n+\tret = air_phy_buckpbus_reg_write(phydev, EN8811H_FW_CTRL_1,\n+\t\t\t\t\t EN8811H_FW_CTRL_1_START);\n \tif (ret < 0)\n \t\tgoto en8811h_load_firmware_out;\n \n-\tret = air_buckpbus_reg_modify(phydev, EN8811H_FW_CTRL_2,\n-\t\t\t\t      EN8811H_FW_CTRL_2_LOADING,\n-\t\t\t\t      EN8811H_FW_CTRL_2_LOADING);\n+\tret = air_phy_buckpbus_reg_modify(phydev, EN8811H_FW_CTRL_2,\n+\t\t\t\t\t  EN8811H_FW_CTRL_2_LOADING,\n+\t\t\t\t\t  EN8811H_FW_CTRL_2_LOADING);\n \tif (ret < 0)\n \t\tgoto en8811h_load_firmware_out;\n \n@@ -727,13 +565,13 @@ static int en8811h_load_firmware(struct phy_device *phydev)\n \tif (ret < 0)\n \t\tgoto en8811h_load_firmware_out;\n \n-\tret = air_buckpbus_reg_modify(phydev, EN8811H_FW_CTRL_2,\n-\t\t\t\t      EN8811H_FW_CTRL_2_LOADING, 0);\n+\tret = air_phy_buckpbus_reg_modify(phydev, EN8811H_FW_CTRL_2,\n+\t\t\t\t\t  EN8811H_FW_CTRL_2_LOADING, 0);\n \tif (ret < 0)\n \t\tgoto en8811h_load_firmware_out;\n \n-\tret = air_buckpbus_reg_write(phydev, EN8811H_FW_CTRL_1,\n-\t\t\t\t     EN8811H_FW_CTRL_1_FINISH);\n+\tret = air_phy_buckpbus_reg_write(phydev, EN8811H_FW_CTRL_1,\n+\t\t\t\t\t EN8811H_FW_CTRL_1_FINISH);\n \tif (ret < 0)\n \t\tgoto en8811h_load_firmware_out;\n \n@@ -741,8 +579,8 @@ static int en8811h_load_firmware(struct phy_device *phydev)\n \tif (ret < 0)\n \t\tgoto en8811h_load_firmware_out;\n \n-\tair_buckpbus_reg_read(phydev, EN8811H_FW_VERSION,\n-\t\t\t      &priv->firmware_version);\n+\tair_phy_buckpbus_reg_read(phydev, EN8811H_FW_VERSION,\n+\t\t\t\t  &priv->firmware_version);\n \n \tdev_info(phydev->dev, \"MD32 firmware version: %08x\\n\",\n \t\t priv->firmware_version);\n@@ -778,8 +616,8 @@ static int an8811hb_load_firmware(struct phy_device *phydev)\n \tif (ret < 0)\n \t\tgoto an8811hb_load_firmware_out;\n \n-\tret = air_buckpbus_reg_write(phydev, AIR_PHY_FW_CTRL_1,\n-\t\t\t\t     AIR_PHY_FW_CTRL_1_START);\n+\tret = air_phy_buckpbus_reg_write(phydev, AIR_PHY_FW_CTRL_1,\n+\t\t\t\t\t AIR_PHY_FW_CTRL_1_START);\n \tif (ret < 0)\n \t\tgoto an8811hb_load_firmware_out;\n \n@@ -803,8 +641,8 @@ static int an8811hb_load_firmware(struct phy_device *phydev)\n \tif (ret < 0)\n \t\tgoto an8811hb_load_firmware_out;\n \n-\tret = air_buckpbus_reg_write(phydev, AIR_PHY_FW_CTRL_1,\n-\t\t\t\t     AIR_PHY_FW_CTRL_1_FINISH);\n+\tret = air_phy_buckpbus_reg_write(phydev, AIR_PHY_FW_CTRL_1,\n+\t\t\t\t\t AIR_PHY_FW_CTRL_1_FINISH);\n \tif (ret < 0)\n \t\tgoto an8811hb_load_firmware_out;\n \n@@ -817,7 +655,7 @@ static int an8811hb_load_firmware(struct phy_device *phydev)\n \tdo {\n \t\tmdelay(300);\n \n-\t\tret = air_buckpbus_reg_read(phydev, AIR_PHY_FW_CTRL_1, &reg_val);\n+\t\tret = air_phy_buckpbus_reg_read(phydev, AIR_PHY_FW_CTRL_1, &reg_val);\n \t\tif (ret < 0)\n \t\t\tgoto an8811hb_load_firmware_out;\n \n@@ -827,8 +665,8 @@ static int an8811hb_load_firmware(struct phy_device *phydev)\n \t\tdebug(\"%d: reg 0x%x val 0x%x!\\n\", __LINE__, AIR_PHY_FW_CTRL_1,\n \t\t      reg_val);\n \n-\t\tret = air_buckpbus_reg_write(phydev, AIR_PHY_FW_CTRL_1,\n-\t\t\t\t\t     AIR_PHY_FW_CTRL_1_FINISH);\n+\t\tret = air_phy_buckpbus_reg_write(phydev, AIR_PHY_FW_CTRL_1,\n+\t\t\t\t\t\t AIR_PHY_FW_CTRL_1_FINISH);\n \t\tif (ret < 0)\n \t\t\tgoto an8811hb_load_firmware_out;\n \n@@ -838,8 +676,8 @@ static int an8811hb_load_firmware(struct phy_device *phydev)\n \tif (ret < 0)\n \t\tgoto an8811hb_load_firmware_out;\n \n-\tair_buckpbus_reg_read(phydev, AIR_PHY_MD32FW_VERSION,\n-\t\t\t      &priv->firmware_version);\n+\tair_phy_buckpbus_reg_read(phydev, AIR_PHY_MD32FW_VERSION,\n+\t\t\t\t  &priv->firmware_version);\n \n \tdebug(\"MD32 firmware version: %08x\\n\", priv->firmware_version);\n \n@@ -858,17 +696,17 @@ int an8811hb_cko_cfg(struct phy_device *phydev)\n \tint ret = 0;\n \n \tif (!ofnode_read_bool(node, \"airoha,phy-output-clock\")) {\n-\t\tret = air_buckpbus_reg_modify(phydev, AN8811HB_CLK_DRV,\n-\t\t\t\t\t      AN8811HB_CLK_DRV_CKO_MASK,\n-\t\t\t\t\t      AN8811HB_CLK_DRV_CKOPWD    |\n-\t\t\t\t\t      AN8811HB_CLK_DRV_CKO_LDPWD |\n-\t\t\t\t\t      AN8811HB_CLK_DRV_CKO_LPPWD);\n+\t\tret = air_phy_buckpbus_reg_modify(phydev, AN8811HB_CLK_DRV,\n+\t\t\t\t\t\t  AN8811HB_CLK_DRV_CKO_MASK,\n+\t\t\t\t\t\t  AN8811HB_CLK_DRV_CKOPWD    |\n+\t\t\t\t\t\t  AN8811HB_CLK_DRV_CKO_LDPWD |\n+\t\t\t\t\t\t  AN8811HB_CLK_DRV_CKO_LPPWD);\n \t\tif (ret < 0)\n \t\t\treturn ret;\n \n \t\tdebug(\"CKO Output mode - Disabled\\n\");\n \t} else {\n-\t\tret = air_buckpbus_reg_read(phydev, AN8811HB_HWTRAP2, &pbus_value);\n+\t\tret = air_phy_buckpbus_reg_read(phydev, AN8811HB_HWTRAP2, &pbus_value);\n \t\tif (ret < 0)\n \t\t\treturn ret;\n \n@@ -887,13 +725,13 @@ static int en8811h_restart_mcu(struct phy_device *phydev)\n \tif (ret < 0)\n \t\treturn ret;\n \n-\tret = air_buckpbus_reg_write(phydev, EN8811H_FW_CTRL_1,\n-\t\t\t\t     EN8811H_FW_CTRL_1_START);\n+\tret = air_phy_buckpbus_reg_write(phydev, EN8811H_FW_CTRL_1,\n+\t\t\t\t\t EN8811H_FW_CTRL_1_START);\n \tif (ret < 0)\n \t\treturn ret;\n \n-\treturn air_buckpbus_reg_write(phydev, EN8811H_FW_CTRL_1,\n-\t\t\t\t      EN8811H_FW_CTRL_1_FINISH);\n+\treturn air_phy_buckpbus_reg_write(phydev, EN8811H_FW_CTRL_1,\n+\t\t\t\t\t  EN8811H_FW_CTRL_1_FINISH);\n }\n \n static int air_led_hw_control_set(struct phy_device *phydev, u8 index,\n@@ -1091,10 +929,10 @@ static int en8811h_config(struct phy_device *phydev)\n \t\tpbus_value &= ~EN8811H_POLARITY_TX_NORMAL;\n \telse\n \t\tpbus_value |=  EN8811H_POLARITY_TX_NORMAL;\n-\tret = air_buckpbus_reg_modify(phydev, EN8811H_POLARITY,\n-\t\t\t\t      EN8811H_POLARITY_RX_REVERSE |\n-\t\t\t\t      EN8811H_POLARITY_TX_NORMAL,\n-\t\t\t\t      pbus_value);\n+\tret = air_phy_buckpbus_reg_modify(phydev, EN8811H_POLARITY,\n+\t\t\t\t\t  EN8811H_POLARITY_RX_REVERSE |\n+\t\t\t\t\t  EN8811H_POLARITY_TX_NORMAL,\n+\t\t\t\t\t  pbus_value);\n \tif (ret < 0)\n \t\treturn ret;\n \n@@ -1142,12 +980,12 @@ static int an8811hb_config(struct phy_device *phydev)\n \t\tpriv->mcu_needs_restart = true;\n \t}\n \n-\tret = air_buckpbus_reg_read(phydev, AN8811HB_PRO_ID, &pbus_value);\n+\tret = air_phy_buckpbus_reg_read(phydev, AN8811HB_PRO_ID, &pbus_value);\n \tif (ret < 0)\n \t\treturn ret;\n \tpriv->pro_id = (pbus_value & AN8811HB_PRO_ID_VERSION) + 1;\n \n-\tret = air_buckpbus_reg_read(phydev, AN8811HB_HWTRAP2, &pbus_value);\n+\tret = air_phy_buckpbus_reg_read(phydev, AN8811HB_HWTRAP2, &pbus_value);\n \tif (ret < 0)\n \t\treturn ret;\n \tpriv->pkg_sel = (pbus_value & AN8811HB_HWTRAP2_PKG) >> 12;\n@@ -1163,8 +1001,8 @@ static int an8811hb_config(struct phy_device *phydev)\n \t\tpbus_value |= AN8811HB_RX_POLARITY_NORMAL;\n \n \tdebug(\"1 pbus_value 0x%x\\n\", pbus_value);\n-\tret = air_buckpbus_reg_modify(phydev, AN8811HB_RX_POLARITY,\n-\t\t\t\t      AN8811HB_RX_POLARITY_NORMAL, pbus_value);\n+\tret = air_phy_buckpbus_reg_modify(phydev, AN8811HB_RX_POLARITY,\n+\t\t\t\t\t  AN8811HB_RX_POLARITY_NORMAL, pbus_value);\n \tif (ret < 0)\n \t\treturn ret;\n \n@@ -1175,35 +1013,35 @@ static int an8811hb_config(struct phy_device *phydev)\n \t\tpbus_value |= AN8811HB_TX_POLARITY_NORMAL;\n \n \tdebug(\"2 pbus_value 0x%x\\n\", pbus_value);\n-\tret = air_buckpbus_reg_modify(phydev, AN8811HB_TX_POLARITY,\n-\t\t\t\t      AN8811HB_TX_POLARITY_NORMAL, pbus_value);\n+\tret = air_phy_buckpbus_reg_modify(phydev, AN8811HB_TX_POLARITY,\n+\t\t\t\t\t  AN8811HB_TX_POLARITY_NORMAL, pbus_value);\n \tif (ret < 0)\n \t\treturn ret;\n \n \t/* Configure led gpio pins as output */\n \tif (priv->pkg_sel) {\n-\t\tret = air_buckpbus_reg_modify(phydev, AN8811HB_GPIO_OUTPUT,\n-\t\t\t\t\t      AN8811HB_GPIO_OUTPUT_MASK,\n-\t\t\t\t\t      AN8811HB_GPIO_OUTPUT_0115);\n+\t\tret = air_phy_buckpbus_reg_modify(phydev, AN8811HB_GPIO_OUTPUT,\n+\t\t\t\t\t\t  AN8811HB_GPIO_OUTPUT_MASK,\n+\t\t\t\t\t\t  AN8811HB_GPIO_OUTPUT_0115);\n \t\tif (ret < 0)\n \t\t\treturn ret;\n-\t\tret = air_buckpbus_reg_modify(phydev, AN8811HB_GPIO_SEL_1,\n-\t\t\t\t\t      AN8811HB_GPIO_SEL_1_0_MASK |\n-\t\t\t\t\t      AN8811HB_GPIO_SEL_1_1_MASK,\n-\t\t\t\t\t      AN8811HB_GPIO_SEL_1_0 |\n-\t\t\t\t\t      AN8811HB_GPIO_SEL_1_1);\n+\t\tret = air_phy_buckpbus_reg_modify(phydev, AN8811HB_GPIO_SEL_1,\n+\t\t\t\t\t\t  AN8811HB_GPIO_SEL_1_0_MASK |\n+\t\t\t\t\t\t  AN8811HB_GPIO_SEL_1_1_MASK,\n+\t\t\t\t\t\t  AN8811HB_GPIO_SEL_1_0 |\n+\t\t\t\t\t\t  AN8811HB_GPIO_SEL_1_1);\n \t\tif (ret < 0)\n \t\t\treturn ret;\n \n-\t\tret = air_buckpbus_reg_modify(phydev, AN8811HB_GPIO_SEL_2,\n-\t\t\t\t\t      AN8811HB_GPIO_SEL_2_15_MASK,\n-\t\t\t\t\t      AN8811HB_GPIO_SEL_2_15);\n+\t\tret = air_phy_buckpbus_reg_modify(phydev, AN8811HB_GPIO_SEL_2,\n+\t\t\t\t\t\t  AN8811HB_GPIO_SEL_2_15_MASK,\n+\t\t\t\t\t\t  AN8811HB_GPIO_SEL_2_15);\n \t\tif (ret < 0)\n \t\t\treturn ret;\n \t} else {\n-\t\tret = air_buckpbus_reg_modify(phydev, AN8811HB_GPIO_OUTPUT,\n-\t\t\t\t\t      AN8811HB_GPIO_OUTPUT_345,\n-\t\t\t\t\t      AN8811HB_GPIO_OUTPUT_345);\n+\t\tret = air_phy_buckpbus_reg_modify(phydev, AN8811HB_GPIO_OUTPUT,\n+\t\t\t\t\t\t  AN8811HB_GPIO_OUTPUT_345,\n+\t\t\t\t\t\t  AN8811HB_GPIO_OUTPUT_345);\n \t\tif (ret < 0)\n \t\t\treturn ret;\n \t}\n@@ -1373,16 +1211,6 @@ static int en8811h_probe(struct phy_device *phydev)\n \treturn 0;\n }\n \n-static int air_phy_read_page(struct phy_device *phydev)\n-{\n-\treturn phy_read(phydev, MDIO_DEVAD_NONE, AIR_EXT_PAGE_ACCESS);\n-}\n-\n-static int air_phy_write_page(struct phy_device *phydev, int page)\n-{\n-\treturn phy_write(phydev, MDIO_DEVAD_NONE, AIR_EXT_PAGE_ACCESS, page);\n-}\n-\n U_BOOT_PHY_DRIVER(en8811h) = {\n \t.name = \"Airoha EN8811H\",\n \t.uid = EN8811H_PHY_ID,\ndiff --git a/drivers/net/phy/airoha/air_phy_lib.c b/drivers/net/phy/airoha/air_phy_lib.c\nnew file mode 100644\nindex 00000000000..61c3bf82822\n--- /dev/null\n+++ b/drivers/net/phy/airoha/air_phy_lib.c\n@@ -0,0 +1,216 @@\n+// SPDX-License-Identifier: GPL-2.0+\n+/*\n+ * Airoha Ethernet PHY common library\n+ *\n+ * Copyright (C) 2026 Airoha Technology Corp.\n+ * Copyright (C) 2026 Collabora Ltd.\n+ *                    Louis-Alexis Eyraud <louisalexis.eyraud@collabora.com>\n+ *\n+ * Adapated from https://lore.kernel.org/all/20260326-add-airoha-an8801-support-v2-2-1a42d6b6050f@collabora.com/\n+ */\n+\n+#include <dm/device_compat.h>\n+#include <linux/compat.h>\n+#include <phy.h>\n+\n+#include \"air_phy_lib.h\"\n+\n+#define AIR_EXT_PAGE_ACCESS\t0x1f\n+\n+static int __air_buckpbus_reg_read(struct phy_device *phydev,\n+\t\t\t\t   u32 pbus_address, u32 *pbus_data)\n+{\n+\tint pbus_data_low, pbus_data_high;\n+\tint ret;\n+\n+\tret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_MODE,\n+\t\t\tAIR_BPBUS_MODE_ADDR_FIXED);\n+\tif (ret < 0)\n+\t\treturn ret;\n+\n+\tret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_RD_ADDR_HIGH,\n+\t\t\tupper_16_bits(pbus_address));\n+\tif (ret < 0)\n+\t\treturn ret;\n+\n+\tret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_RD_ADDR_LOW,\n+\t\t\tlower_16_bits(pbus_address));\n+\tif (ret < 0)\n+\t\treturn ret;\n+\n+\tpbus_data_high = phy_read(phydev, MDIO_DEVAD_NONE,\n+\t\t\t\t  AIR_BPBUS_RD_DATA_HIGH);\n+\tif (pbus_data_high < 0)\n+\t\treturn pbus_data_high;\n+\n+\tpbus_data_low = phy_read(phydev, MDIO_DEVAD_NONE,\n+\t\t\t\t AIR_BPBUS_RD_DATA_LOW);\n+\tif (pbus_data_low < 0)\n+\t\treturn pbus_data_low;\n+\n+\t*pbus_data = pbus_data_low | (pbus_data_high << 16);\n+\treturn 0;\n+}\n+\n+static int __air_buckpbus_reg_write(struct phy_device *phydev,\n+\t\t\t\t    u32 pbus_address, u32 pbus_data)\n+{\n+\tint ret;\n+\n+\tret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_MODE,\n+\t\t\tAIR_BPBUS_MODE_ADDR_FIXED);\n+\tif (ret < 0)\n+\t\treturn ret;\n+\n+\tret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_WR_ADDR_HIGH,\n+\t\t\tupper_16_bits(pbus_address));\n+\tif (ret < 0)\n+\t\treturn ret;\n+\n+\tret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_WR_ADDR_LOW,\n+\t\t\tlower_16_bits(pbus_address));\n+\tif (ret < 0)\n+\t\treturn ret;\n+\n+\tret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_WR_DATA_HIGH,\n+\t\t\tupper_16_bits(pbus_data));\n+\tif (ret < 0)\n+\t\treturn ret;\n+\n+\tret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_WR_DATA_LOW,\n+\t\t\tlower_16_bits(pbus_data));\n+\tif (ret < 0)\n+\t\treturn ret;\n+\n+\treturn 0;\n+}\n+\n+static int __air_buckpbus_reg_modify(struct phy_device *phydev,\n+\t\t\t\t     u32 pbus_address, u32 mask, u32 set)\n+{\n+\tint pbus_data_low, pbus_data_high;\n+\tu32 pbus_data_old, pbus_data_new;\n+\tint ret;\n+\n+\tret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_MODE,\n+\t\t\tAIR_BPBUS_MODE_ADDR_FIXED);\n+\tif (ret < 0)\n+\t\treturn ret;\n+\n+\tret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_RD_ADDR_HIGH,\n+\t\t\tupper_16_bits(pbus_address));\n+\tif (ret < 0)\n+\t\treturn ret;\n+\n+\tret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_RD_ADDR_LOW,\n+\t\t\tlower_16_bits(pbus_address));\n+\tif (ret < 0)\n+\t\treturn ret;\n+\n+\tpbus_data_high = phy_read(phydev, MDIO_DEVAD_NONE,\n+\t\t\t\t  AIR_BPBUS_RD_DATA_HIGH);\n+\tif (pbus_data_high < 0)\n+\t\treturn pbus_data_high;\n+\n+\tpbus_data_low = phy_read(phydev, MDIO_DEVAD_NONE,\n+\t\t\t\t AIR_BPBUS_RD_DATA_LOW);\n+\tif (pbus_data_low < 0)\n+\t\treturn pbus_data_low;\n+\n+\tpbus_data_old = pbus_data_low | (pbus_data_high << 16);\n+\tpbus_data_new = (pbus_data_old & ~mask) | set;\n+\tif (pbus_data_new == pbus_data_old)\n+\t\treturn 0;\n+\n+\tret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_WR_ADDR_HIGH,\n+\t\t\tupper_16_bits(pbus_address));\n+\tif (ret < 0)\n+\t\treturn ret;\n+\n+\tret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_WR_ADDR_LOW,\n+\t\t\tlower_16_bits(pbus_address));\n+\tif (ret < 0)\n+\t\treturn ret;\n+\n+\tret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_WR_DATA_HIGH,\n+\t\t\tupper_16_bits(pbus_data_new));\n+\tif (ret < 0)\n+\t\treturn ret;\n+\n+\tret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_WR_DATA_LOW,\n+\t\t\tlower_16_bits(pbus_data_new));\n+\tif (ret < 0)\n+\t\treturn ret;\n+\n+\treturn 0;\n+}\n+\n+int air_phy_buckpbus_reg_read(struct phy_device *phydev, u32 pbus_address,\n+\t\t\t      u32 *pbus_data)\n+{\n+\tint saved_page;\n+\tint ret = 0;\n+\n+\tsaved_page = phy_select_page(phydev, AIR_PHY_PAGE_EXTENDED_4);\n+\n+\tif (saved_page >= 0) {\n+\t\tret = __air_buckpbus_reg_read(phydev, pbus_address, pbus_data);\n+\t\tif (ret < 0)\n+\t\t\tdev_err(phydev->dev, \"%s 0x%08x failed: %d\\n\", __func__,\n+\t\t\t\tpbus_address, ret);\n+\t}\n+\n+\treturn phy_restore_page(phydev, saved_page, ret);\n+}\n+\n+int air_phy_buckpbus_reg_write(struct phy_device *phydev, u32 pbus_address,\n+\t\t\t       u32 pbus_data)\n+{\n+\tint saved_page;\n+\tint ret = 0;\n+\n+\tsaved_page = phy_select_page(phydev, AIR_PHY_PAGE_EXTENDED_4);\n+\n+\tif (saved_page >= 0) {\n+\t\tret = __air_buckpbus_reg_write(phydev, pbus_address,\n+\t\t\t\t\t       pbus_data);\n+\t\tif (ret < 0)\n+\t\t\tdev_err(phydev->dev, \"%s 0x%08x failed: %d\\n\", __func__,\n+\t\t\t\tpbus_address, ret);\n+\t}\n+\n+\treturn phy_restore_page(phydev, saved_page, ret);\n+}\n+\n+int air_phy_buckpbus_reg_modify(struct phy_device *phydev, u32 pbus_address,\n+\t\t\t\tu32 mask, u32 set)\n+{\n+\tint saved_page;\n+\tint ret = 0;\n+\n+\tsaved_page = phy_select_page(phydev, AIR_PHY_PAGE_EXTENDED_4);\n+\n+\tif (saved_page >= 0) {\n+\t\tret = __air_buckpbus_reg_modify(phydev, pbus_address, mask,\n+\t\t\t\t\t\tset);\n+\t\tif (ret < 0)\n+\t\t\tdev_err(phydev->dev, \"%s 0x%08x failed: %d\\n\", __func__,\n+\t\t\t\tpbus_address, ret);\n+\t}\n+\n+\treturn phy_restore_page(phydev, saved_page, ret);\n+}\n+\n+int air_phy_read_page(struct phy_device *phydev)\n+{\n+\treturn phy_read(phydev, MDIO_DEVAD_NONE, AIR_EXT_PAGE_ACCESS);\n+}\n+\n+int air_phy_write_page(struct phy_device *phydev, int page)\n+{\n+\treturn phy_write(phydev, MDIO_DEVAD_NONE, AIR_EXT_PAGE_ACCESS, page);\n+}\n+\n+MODULE_DESCRIPTION(\"Airoha PHY Library\");\n+MODULE_LICENSE(\"GPL\");\n+MODULE_AUTHOR(\"Louis-Alexis Eyraud\");\ndiff --git a/drivers/net/phy/airoha/air_phy_lib.h b/drivers/net/phy/airoha/air_phy_lib.h\nnew file mode 100644\nindex 00000000000..845d2f7cfb4\n--- /dev/null\n+++ b/drivers/net/phy/airoha/air_phy_lib.h\n@@ -0,0 +1,39 @@\n+/* SPDX-License-Identifier: GPL-2.0+ */\n+/*\n+ * Copyright (C) 2026 Airoha Technology Corp.\n+ * Copyright (C) 2026 Collabora Ltd.\n+ *                    Louis-Alexis Eyraud <louisalexis.eyraud@collabora.com>\n+ */\n+\n+#ifndef __AIR_PHY_LIB_H\n+#define __AIR_PHY_LIB_H\n+\n+#define AIR_EXT_PAGE_ACCESS\t0x1f\n+\n+#define AIR_PHY_PAGE_STANDARD\t\t0x0000\n+#define AIR_PHY_PAGE_EXTENDED_1\t\t0x0001\n+#define AIR_PHY_PAGE_EXTENDED_4\t\t0x0004\n+\n+/* MII Registers Page 4*/\n+#define AIR_BPBUS_MODE\t\t\t0x10\n+#define   AIR_BPBUS_MODE_ADDR_FIXED\t0x0000\n+#define   AIR_BPBUS_MODE_ADDR_INCR\tBIT(15)\n+#define AIR_BPBUS_WR_ADDR_HIGH\t\t0x11\n+#define AIR_BPBUS_WR_ADDR_LOW\t\t0x12\n+#define AIR_BPBUS_WR_DATA_HIGH\t\t0x13\n+#define AIR_BPBUS_WR_DATA_LOW\t\t0x14\n+#define AIR_BPBUS_RD_ADDR_HIGH\t\t0x15\n+#define AIR_BPBUS_RD_ADDR_LOW\t\t0x16\n+#define AIR_BPBUS_RD_DATA_HIGH\t\t0x17\n+#define AIR_BPBUS_RD_DATA_LOW\t\t0x18\n+\n+int air_phy_buckpbus_reg_modify(struct phy_device *phydev, u32 pbus_address,\n+\t\t\t\tu32 mask, u32 set);\n+int air_phy_buckpbus_reg_read(struct phy_device *phydev, u32 pbus_address,\n+\t\t\t      u32 *pbus_data);\n+int air_phy_buckpbus_reg_write(struct phy_device *phydev, u32 pbus_address,\n+\t\t\t       u32 pbus_data);\n+int air_phy_read_page(struct phy_device *phydev);\n+int air_phy_write_page(struct phy_device *phydev, int page);\n+\n+#endif /* __AIR_PHY_LIB_H */\n",
    "prefixes": [
        "v2",
        "5/9"
    ]
}