From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-ej1-f52.google.com (mail-ej1-f52.google.com [209.85.218.52]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C4AE43A0E88 for ; Thu, 26 Mar 2026 20:00:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.52 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774555207; cv=none; b=VZ1Rm63ju2m9eCBPmqoLB66BJlqflBPyFpgCNa/Vt3EVJU2Tjvqzx9BjuliSDYNFIi9aSvMwhblhwBwPSMWAjJO+OJCW/W4DXoCFMwKDsxCtghcUgQPebDlagh7TTljUB0PxPHN/kPMeH6UeNPmkhSQ2LhJB8N5APUGt2hJfERY= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774555207; c=relaxed/simple; bh=sZCu+zV806RkYMwGhzwSVjIEcYHK2rC1VqIBfMqEoWM=; h=Message-ID:Date:MIME-Version:Subject:To:Cc:References:From: In-Reply-To:Content-Type; b=H/lzbCBBQjLUhvPZufBVfFE9kKyrHfLfX0NFoJmjr3N51MHyjARf9c08L6m8XB5p00uVGZAHJ9fwbNY/oyWqyfKuw4T1nGF3G+Kvrp/tA+EUlwkKS8VKIgRdFC5lemhZR8beIGuMi8P2imV1Rg7G4E0YwyzEf/uhitQGjP1IcYk= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=VxAsTmHQ; arc=none smtp.client-ip=209.85.218.52 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="VxAsTmHQ" Received: by mail-ej1-f52.google.com with SMTP id a640c23a62f3a-b9825ba7f9dso374479366b.0 for ; Thu, 26 Mar 2026 13:00:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1774555203; x=1775160003; darn=vger.kernel.org; h=content-transfer-encoding:in-reply-to:from:content-language :references:cc:to:subject:user-agent:mime-version:date:message-id :from:to:cc:subject:date:message-id:reply-to; bh=DmJ4jvJu+2RaqY+ZPxeE/qs9ff0J/6mOVazKfaw6kqU=; b=VxAsTmHQGTLncq6sOArDnMx+aWMA05cVd0MZ9KsFEDkrBAnaablj3jiVJLaVOS29NZ 4gI/ocRd1PWz0bYubAV7fbtwhcnX8MK22B/xIHrD5xxK/THDecAXwiR7+NUJTBp8rsYw XH4RGuQ1XBWyAKvthj2zFEtqEixc3iPSje507SuWouwt/b1192Jt1Vcy0AwJj/ZVzbSM 8yMYvpANEqMfT4le14yTrFfaK1RRcVoH0tUVAL54aAgA/3QUVOutQq6+Wbmu354kEEU7 wu9G13WDFQc8VB4sevXZ4Zz3jzhFbWTbi9518ZRRNd8PHAq0Fu19QRwYQNeXJPnEKN3c fWjw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1774555203; x=1775160003; h=content-transfer-encoding:in-reply-to:from:content-language :references:cc:to:subject:user-agent:mime-version:date:message-id :x-gm-gg:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=DmJ4jvJu+2RaqY+ZPxeE/qs9ff0J/6mOVazKfaw6kqU=; b=gVEN2a4BNkmzi4Ui2cUX37dPDcRGJ2FzG043LTpWgyE3nL/vTF/pHpmEyPFPDJBHlx Y7jzLqEH/pyzdImCUQlqcdislwxbXOj13JVc+vIvYACrivBlSi/C7KnzKBRyj1253Knr 5m8lZDcQWrsODo2IJ+Nz+noMIsdoZfj+KhEkarFyYrBp1GOLZNS/m9c3DyoeTK5ottjx QyD8sczWOlp1BxCPgxyYQntbXmLPf8bJ5aYQBWewMQzxZQhG3lPRGalFcUd09Yj+bqzB izWsckZp0d5eHepS5ahgce/uGAIipdkemdKChTeKkv4RlEpZKS9wNSXrfz1T/BLCggLC TA+g== X-Forwarded-Encrypted: i=1; AJvYcCVVnLtqAjvVE8RDd7CIE+DuowbEer4yWdHuJu/ORUjfBudk1waQ89NdPCg3Ynn2SM7ssUOZU3BLbudIlas=@vger.kernel.org X-Gm-Message-State: AOJu0YzmaYhQnawolawHhUz+eLcO2cvbu7ZwPqaH2AH811TpegINuAJc v0Rd21VsbQqQTZ+JrXbCBRW7xJaucYvgmH80sExuLj8dx/Oxl2sn3o2K X-Gm-Gg: ATEYQzyy23MbFU/atHCizsxT1eVkSWhopE2SpVlL9UWTHo7C2y2mlD8S8XIhK++RCeo VU/h1eEY+8Xyrzt4LQJtMYPcBAYARbwRUjq5M/+GhbCKkKBzU/KYpyEW44ldk5GDH/6Zlc0KgUT 3d6aIvFhljDqVASDG7J9zEiAtuRRGg6d1t/k93oRX9V3tjkVq/9VeEvNpNY4ACoGrD9PW92PZtL /qB83vuWvSecQCNnG3qRiI5pJjs92kbGHq7yq2HFTD8Sihr0x51NZmrQaU+bUaKRn+3X0Btlu+h JrlK6PiCrfq29FZkRHyG+CqffBSmA9Huwc4pLwEbYkwf2XVM5QiDw8R26AlQaUunXuwjvSPmMre ck+jBuebnf+VHnVqRFmIFmd4Vdna/wsCpxcWVu+56HP/9qsnMjSsJPZ52/4JotrQxzR/sPQdG2y 119PfwLoeER04kVz906Rmm1pN5svaqI+dLBuLuLDd6dP5JYU1vqdPKbJKIsNPFSyxlQsvsFwS8e HauV4IT32AA16Jpvj6hVHVDQ9GAMKD8ym5t7xCBvSL9ga0LPxwhq7syrhjfTnadihW5n46W8AWs iLl5KsUFxzdzLbD8V3S8DyLlar/5GImswA== X-Received: by 2002:a17:907:c0e:b0:b9b:207c:f7e4 with SMTP id a640c23a62f3a-b9b2e75d17bmr214143366b.13.1774555202793; Thu, 26 Mar 2026 13:00:02 -0700 (PDT) Received: from ?IPV6:2001:1c00:20d:1300:1b1c:4449:176a:89ea? (2001-1c00-020d-1300-1b1c-4449-176a-89ea.cable.dynamic.v6.ziggo.nl. [2001:1c00:20d:1300:1b1c:4449:176a:89ea]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-b9b2042f7e9sm162059466b.56.2026.03.26.13.00.01 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 26 Mar 2026 13:00:02 -0700 (PDT) Message-ID: Date: Thu, 26 Mar 2026 21:00:01 +0100 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: [PATCH v2] net: phy: air_en8811h: add AN8811HB MCU assert/deassert support To: "Lucien.Jheng" , andrew@lunn.ch, hkallweit1@gmail.com, linux@armlinux.org.uk, davem@davemloft.net, edumazet@google.com, kuba@kernel.org, pabeni@redhat.com, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, bjorn@mork.no Cc: frank-w@public-files.de, daniel@makrotopia.org, lucien.jheng@airoha.com References: <20260326153518.8387-1-lucienzx159@gmail.com> Content-Language: en-US From: Eric Woudstra In-Reply-To: <20260326153518.8387-1-lucienzx159@gmail.com> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit On 3/26/26 4:35 PM, Lucien.Jheng wrote: > AN8811HB needs a MCU soft-reset cycle before firmware loading begins. > Assert the MCU (hold it in reset) and immediately deassert (release) > via a dedicated PBUS register pair (0x5cf9f8 / 0x5cf9fc), accessed > through the PHY-addr+8 MDIO bus node rather than the BUCKPBUS indirect > path. This clears the MCU state before the firmware loading sequence > starts. Perhapse you can register this extra device in the probe() function: struct mdio_device *mdiodev; mdiodev = mdio_device_create(phydev->mdio.bus, phydev->mdio.addr + EN8811H_PBUS_ADDR_OFFS); if (IS_ERR(mdiodev)) return PTR_ERR(mdiodev); ret = mdio_device_register(mdiodev); if (ret) { mdio_device_free(mdiodev); return ret; } priv->pbusdev = mdiodev; In the define part add: #define EN8811H_PBUS_ADDR_OFFS 8 Add to struct en8811h_priv: struct mdio_device *pbusdev; And in the remove function: mdio_device_remove(priv->pbusdev); mdio_device_free(priv->pbusdev); Then you can use the device: ret = en8811hb_some_neat_function(priv->pbusdev); > > Add __air_pbus_reg_write() as a low-level helper for this access, then > implement an8811hb_mcu_assert() / _deassert() on top of it. Wire both > into an8811hb_load_firmware() and en8811h_restart_mcu() so every > firmware load or MCU restart on AN8811HB correctly sequences the reset > control registers. > > Fixes: 0a55766b7711 ("net: phy: air_en8811h: add Airoha AN8811HB support") > Signed-off-by: Lucien Jheng > --- > Changes in v2: > - Rewrite commit message: The previous wording was ambiguous, > as it suggested the MCU remains asserted during the entire > firmware loading process, rather than a quick reset cycle > before it starts. > Clarify that assert and deassert is an immediate soft-reset > cycle to clear MCU state before firmware loading begins. > - Add Fixes: 0a55766b7711 ("net: phy: air_en8811h: add Airoha AN8811HB > support"). > - Change phydev_info() to phydev_dbg() in an8811hb_mcu_assert() and > an8811hb_mcu_deassert() to avoid noise during normal boot. > > drivers/net/phy/air_en8811h.c | 105 ++++++++++++++++++++++++++++++++++ > 1 file changed, 105 insertions(+) > > diff --git a/drivers/net/phy/air_en8811h.c b/drivers/net/phy/air_en8811h.c > index 29ae73e65caa..01fce1b93618 100644 > --- a/drivers/net/phy/air_en8811h.c > +++ b/drivers/net/phy/air_en8811h.c > @@ -170,6 +170,16 @@ > #define AN8811HB_CLK_DRV_CKO_LDPWD BIT(13) > #define AN8811HB_CLK_DRV_CKO_LPPWD BIT(14) > > +#define AN8811HB_MCU_SW_RST 0x5cf9f8 > +#define AN8811HB_MCU_SW_RST_HOLD BIT(16) > +#define AN8811HB_MCU_SW_RST_RUN (BIT(16) | BIT(0)) > +#define AN8811HB_MCU_SW_START 0x5cf9fc > +#define AN8811HB_MCU_SW_START_EN BIT(16) > + > +/* MII register constants for PBUS access (PHY addr + 8) */ > +#define AIR_PBUS_ADDR_HIGH 0x1c > +#define AIR_PBUS_DATA_HIGH 0x10 > + > /* Led definitions */ > #define EN8811H_LED_COUNT 3 > > @@ -254,6 +264,36 @@ static int air_phy_write_page(struct phy_device *phydev, int page) > return __phy_write(phydev, AIR_EXT_PAGE_ACCESS, page); > } > > +static int __air_pbus_reg_write(struct phy_device *phydev, > + u32 pbus_reg, u32 pbus_data) > +{ > + struct mii_bus *bus = phydev->mdio.bus; > + int pbus_addr = phydev->mdio.addr + 8; > + int ret; > + > + ret = __mdiobus_write(bus, pbus_addr, AIR_EXT_PAGE_ACCESS, > + upper_16_bits(pbus_reg)); > + if (ret < 0) > + return ret; > + > + ret = __mdiobus_write(bus, pbus_addr, AIR_PBUS_ADDR_HIGH, > + (pbus_reg & GENMASK(15, 6)) >> 6); > + if (ret < 0) > + return ret; > + > + ret = __mdiobus_write(bus, pbus_addr, (pbus_reg & GENMASK(5, 2)) >> 2, > + lower_16_bits(pbus_data)); > + if (ret < 0) > + return ret; > + > + ret = __mdiobus_write(bus, pbus_addr, AIR_PBUS_DATA_HIGH, > + upper_16_bits(pbus_data)); > + if (ret < 0) > + return ret; > + > + return 0; > +} > + > static int __air_buckpbus_reg_write(struct phy_device *phydev, > u32 pbus_address, u32 pbus_data) > { > @@ -570,10 +610,65 @@ static int an8811hb_load_file(struct phy_device *phydev, const char *name, > return ret; > } > > +static int an8811hb_mcu_assert(struct phy_device *phydev) > +{ > + int ret; > + > + phy_lock_mdio_bus(phydev); > + > + ret = __air_pbus_reg_write(phydev, AN8811HB_MCU_SW_RST, > + AN8811HB_MCU_SW_RST_HOLD); > + if (ret < 0) > + goto unlock; > + > + ret = __air_pbus_reg_write(phydev, AN8811HB_MCU_SW_START, 0); > + if (ret < 0) > + goto unlock; > + > + msleep(50); > + phydev_dbg(phydev, "MCU asserted\n"); > + > +unlock: > + phy_unlock_mdio_bus(phydev); > + return ret; > +} > + > +static int an8811hb_mcu_deassert(struct phy_device *phydev) > +{ > + int ret; > + > + phy_lock_mdio_bus(phydev); > + > + ret = __air_pbus_reg_write(phydev, AN8811HB_MCU_SW_START, > + AN8811HB_MCU_SW_START_EN); > + if (ret < 0) > + goto unlock; > + > + ret = __air_pbus_reg_write(phydev, AN8811HB_MCU_SW_RST, > + AN8811HB_MCU_SW_RST_RUN); > + if (ret < 0) > + goto unlock; > + > + msleep(50); > + phydev_dbg(phydev, "MCU deasserted\n"); > + > +unlock: > + phy_unlock_mdio_bus(phydev); > + return ret; > +} > + > static int an8811hb_load_firmware(struct phy_device *phydev) > { > int ret; > > + ret = an8811hb_mcu_assert(phydev); > + if (ret < 0) > + return ret; > + > + ret = an8811hb_mcu_deassert(phydev); > + if (ret < 0) > + return ret; > + > ret = air_buckpbus_reg_write(phydev, EN8811H_FW_CTRL_1, > EN8811H_FW_CTRL_1_START); > if (ret < 0) > @@ -662,6 +757,16 @@ static int en8811h_restart_mcu(struct phy_device *phydev) > { > int ret; > > + if (phy_id_compare_model(phydev->phy_id, AN8811HB_PHY_ID)) { > + ret = an8811hb_mcu_assert(phydev); > + if (ret < 0) > + return ret; > + > + ret = an8811hb_mcu_deassert(phydev); > + if (ret < 0) > + return ret; > + } > + > ret = air_buckpbus_reg_write(phydev, EN8811H_FW_CTRL_1, > EN8811H_FW_CTRL_1_START); > if (ret < 0) > -- > 2.34.1 >