From nobody Mon Feb 9 12:01:47 2026 Received: from mail-wm1-f54.google.com (mail-wm1-f54.google.com [209.85.128.54]) (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 B1918332EAD for ; Fri, 23 Jan 2026 12:01:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.54 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769169693; cv=none; b=g0Ac6Mw/l+7Pfiu8g+PmHfhaaBiCxwGbl4szC8J9iFIFFjhFY29NMXxFulzL3xyiMLo8TfFAe5CmqJMzmjnnTAoCkx7LVQOttHpEgUdcliRY0AOke2Zvx9aR9/GTzrE4J7AEDCqrqX0No7tK5W7/hQN53M5yqQ2tZRyMK2MG0Vo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769169693; c=relaxed/simple; bh=lfX/aQXgXu8N99a9UbOqMgD2maNs9TaUPsD2bCWDZ58=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=RSzxeZL/HWt7Uip86DweXIdC7Loxo2a9h08lfEI7CulDpgS2M0jMgMrRx+tDuggop4LHj66cJHc/iQrBI2krtZUqZexuGJR3KXgdfiDr21yoX6VgfKo2QFEjLHaUkRH1VIejU45yDolMD59JnfNWVyy7utdloahJR4YWjYruKQg= 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=Q8fuRRYL; arc=none smtp.client-ip=209.85.128.54 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="Q8fuRRYL" Received: by mail-wm1-f54.google.com with SMTP id 5b1f17b1804b1-47f5c2283b6so15961315e9.1 for ; Fri, 23 Jan 2026 04:01:31 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1769169690; x=1769774490; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=QCpcCt671zec/WYYqXDWL85shhNDDHyWCrlnv8/D0oo=; b=Q8fuRRYLmsdxcIUeKQT90qib33IPQOiaxi55MIcCIuNlgMonENM/B6nIdYmkDZAzPE DznQ136oihrZueP/7Jx2rJ1Oasy3+eMCCGJik8gsucGZDJ70pE65SeSnEQdc3e06dIoM hs8pFc5PqIp7jZrqx+d2R5SaTumbrYvE0ngvAjGxP5xC/7uu27Z0E41j2WnsNqPYOn/W 84VsbA/Cad5ZPbS0BoMvxoDNRxxhBTcSt7YEncCPbAHEVsxYk1yHibShTsiNrduoOhid /1I3OlSi3TK1oJrJu0unxl5OZ/3gwWY5fDi7BCNGDM9mM45gCW+8bG/3QnIe8TCJS920 +hng== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1769169690; x=1769774490; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=QCpcCt671zec/WYYqXDWL85shhNDDHyWCrlnv8/D0oo=; b=sI2uJwrq0OW4Mp/lUEJ+UANg3pDnvZC/RY03nmRs1t1UviGrqW8+v5QQbbnKHQ5dUb 7o2sVkKBSYUDsKVz9HpmRyOp5qv2HIOz/84D8UqXuPXB2gkHh1Ru+DFp3qxDKSrW1XgC I9v8YdbkFG0JJnzstrzgaVeQM65SOz/shzhaZUKEV9W+wg/KnCrBMG+WtNnOvARHzrXw 7/WdFL4JQxL6vCU9EwdjWh8p0Q+AfOh6Hb/kDbYYqulufj4GmecGLVpLHowHwmQuAAs4 irp8DTz7DmHSUKyD5ODSKvqKEl5zuQesdh54x9hU7BXo7PH+VPuwSt31xZSXHq895Rvg OR2w== X-Forwarded-Encrypted: i=1; AJvYcCUS9I/Lz/8j0U7yfBeLlINmrzD9LgOjpBkcZ8Z6Ozqlq5FjWuJ3NyasjmF0P4iM8PMJTCmACMNvWLG4HXQ=@vger.kernel.org X-Gm-Message-State: AOJu0Yy2YYa1Od5q+m6dmV2ftXj+8GEODFrN3pk8MotKzBYilgl1mY2o AdOSRE6xdWf+GjRLSA9yUDOSgIeeUQpB5nzySyWme8wE+abnxdkxHWE5qExg0g3k X-Gm-Gg: AZuq6aLS4TuG1Ii8DyHFBzI5Ua05svh3RS2R7qgFuvapJrpAzUH4qaAjzwMCnbBaWqx aCNNdlJbThEByEe48u2dxMBH9fa3MLlJCVpJ7hPEAyRSz53Vfxx17xu9PKlIS98Jo71Dfnze9A9 rK8Xuj1lhUMen1cNNB3NqKuGik+uoIAK/wxpycj7vm51BW4jK/qRTncJTRPgoEMQxA1FkMGd93P Cktapac5h8Xe0bePOKehlKFnkqICHjAOeEN0kxRXgGwdsr8FGdggruV/ilA0pnOWhm1R3Ea3ZNG 3+grR/Gv/wdYDzOAFcdLPUi+qm1AIlPi9AeZ+3lLufUcfdqFmx2QCgE+S4zL4Jpc9bzvYaaUzD3 wa7Dtc94DXz4tfHv2fn6YTokS8uPhXmnMQ0hZmgeDCSWyReTg88RAieQm2ZqSlMnI5Fg6+Q4PLk Ap6pcbOysNmbP601sYrZA8cJhXTLmBLFiBGWLws0zF X-Received: by 2002:a05:600c:a08e:b0:477:b642:9dc1 with SMTP id 5b1f17b1804b1-4804c9b4afcmr43459265e9.20.1769169688437; Fri, 23 Jan 2026 04:01:28 -0800 (PST) Received: from Ansuel-XPS24 (93-34-88-81.ip49.fastwebnet.it. [93.34.88.81]) by smtp.googlemail.com with ESMTPSA id 5b1f17b1804b1-4804d603ac9sm21575135e9.4.2026.01.23.04.01.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 23 Jan 2026 04:01:28 -0800 (PST) From: Christian Marangi To: Christian Marangi , Andrew Lunn , Heiner Kallweit , Russell King , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , netdev@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [net-next PATCH v2 2/3] net: phy: as21xxx: add support for DBG command Date: Fri, 23 Jan 2026 13:00:30 +0100 Message-ID: <20260123120117.10883-3-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20260123120117.10883-1-ansuelsmth@gmail.com> References: <20260123120117.10883-1-ansuelsmth@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Rework the msg send logic to support sending DBG command. These DBG command use a special way to send and receive data and use data in u8 size and are used to tweak advanced (and later introduced) feature of the PHY. Signed-off-by: Christian Marangi --- drivers/net/phy/as21xxx.c | 190 +++++++++++++++++++++++++++++++------- 1 file changed, 155 insertions(+), 35 deletions(-) diff --git a/drivers/net/phy/as21xxx.c b/drivers/net/phy/as21xxx.c index a5344abde91a..2098fa6a2f63 100644 --- a/drivers/net/phy/as21xxx.c +++ b/drivers/net/phy/as21xxx.c @@ -59,6 +59,10 @@ #define IPC_CMD_SYS_CPU 0x2 /* SYS_CPU */ #define IPC_CMD_BULK_DATA 0xa /* Pass bulk data in ipc registers. */ #define IPC_CMD_BULK_WRITE 0xc /* Write bulk data to memory */ +#define IPC_CMD_DBG 0x16 +#define IPC_CMD_POLL 0x17 +#define IPC_CMD_WRITE_BUF 0x18 +#define IPC_CMD_READ_BUF 0x19 #define IPC_CMD_CFG_PARAM 0x1a /* Write config parameters to memory */ #define IPC_CMD_NG_TESTMODE 0x1b /* Set NG test mode and tone */ #define IPC_CMD_TEMP_MON 0x15 /* Temperature monitoring function */ @@ -115,6 +119,12 @@ /* Sub command of CMD_TEMP_MON */ #define IPC_CMD_TEMP_MON_GET 0x4 =20 +/* Sub command of CMD_DBG */ +#define IPC_DBG_DPC 0x8b + +#define IPC_DATA_DBG_SEC GENMASK(15, 8) +#define IPC_DATA_DBG_CMD GENMASK(7, 0) + #define AS21XXX_MDIO_AN_C22 0xffe0 =20 #define PHY_ID_AS21XXX 0x75009410 @@ -451,18 +461,9 @@ static int aeon_ipc_send_cmd(struct phy_device *phydev, return 0; } =20 -/* If data is NULL, return 0 or negative error. - * If data not NULL, return number of Bytes received from IPC or - * a negative error. - */ -static int aeon_ipc_send_msg(struct phy_device *phydev, - u16 opcode, u16 *data, unsigned int data_len, - u16 *ret_data) +static int aeon_ipc_set_msg_data(struct phy_device *phydev, u16 *data, + unsigned int data_len) { - struct as21xxx_priv *priv =3D phydev->priv; - unsigned int ret_size; - u16 cmd, ret_sts; - int ret; int i; =20 /* IPC have a max of 8 register to transfer data, @@ -475,46 +476,69 @@ static int aeon_ipc_send_msg(struct phy_device *phyde= v, phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_IPC_DATA(i), data[i]); =20 - cmd =3D FIELD_PREP(AEON_IPC_CMD_SIZE, data_len) | - FIELD_PREP(AEON_IPC_CMD_OPCODE, opcode); - - mutex_lock(&priv->ipc_lock); - - ret =3D aeon_ipc_send_cmd(phydev, priv, cmd, &ret_sts); - if (ret) { - phydev_err(phydev, "failed to send ipc msg for %x: %d\n", - opcode, ret); - goto out; - } - - if (!data) - goto out; + return 0; +} =20 - if ((ret_sts & AEON_IPC_STS_STATUS) =3D=3D AEON_IPC_STS_STATUS_ERROR) { - ret =3D -EINVAL; - goto out; - } +static int +aeon_ipc_get_msg_ret_data(struct phy_device *phydev, u16 ret_sts, + u16 *ret_data) __must_hold(&priv->ipc_lock) +{ + unsigned int ret_size; + int ret; + int i; =20 /* Prevent IPC from stack smashing the kernel. * We can't trust IPC to return a good value and we always * preallocate space for 16 Bytes. */ ret_size =3D FIELD_GET(AEON_IPC_STS_SIZE, ret_sts); - if (ret_size > AEON_IPC_DATA_MAX) { - ret =3D -EINVAL; - goto out; - } + if (ret_size > AEON_IPC_DATA_MAX) + return -EINVAL; =20 /* Read data from IPC data register for ret_size value from IPC */ for (i =3D 0; i < DIV_ROUND_UP(ret_size, sizeof(u16)); i++) { ret =3D phy_read_mmd(phydev, MDIO_MMD_VEND1, VEND1_IPC_DATA(i)); if (ret < 0) - goto out; + return ret; =20 ret_data[i] =3D ret; } =20 - ret =3D ret_size; + return ret_size; +} + +/* If data is NULL, return 0 or negative error. + * If data not NULL, return number of Bytes received from IPC or + * a negative error. + */ +static int aeon_ipc_send_msg(struct phy_device *phydev, + u16 opcode, u16 *data, unsigned int data_len, + u16 *ret_data) +{ + struct as21xxx_priv *priv =3D phydev->priv; + u16 cmd, ret_sts; + int ret; + + ret =3D aeon_ipc_set_msg_data(phydev, data, data_len); + if (ret) + return ret; + + cmd =3D FIELD_PREP(AEON_IPC_CMD_SIZE, data_len) | + FIELD_PREP(AEON_IPC_CMD_OPCODE, opcode); + + mutex_lock(&priv->ipc_lock); + + ret =3D aeon_ipc_send_cmd(phydev, priv, cmd, &ret_sts); + if (ret) { + phydev_err(phydev, "failed to send ipc msg for %x: %d\n", + opcode, ret); + goto out; + } + + if (!data) + goto out; + + ret =3D aeon_ipc_get_msg_ret_data(phydev, ret_sts, ret_data); =20 out: mutex_unlock(&priv->ipc_lock); @@ -604,6 +628,102 @@ static int aeon_ipc_get_fw_version(struct phy_device = *phydev) return 0; } =20 +static int aeon_ipc_poll(struct phy_device *phydev) +{ + struct as21xxx_priv *priv =3D phydev->priv; + u16 ret_sts; + u16 cmd; + int ret; + + cmd =3D FIELD_PREP(AEON_IPC_CMD_SIZE, 0) | + FIELD_PREP(AEON_IPC_CMD_OPCODE, IPC_CMD_POLL); + + mutex_lock(&priv->ipc_lock); + + ret =3D aeon_ipc_send_cmd(phydev, phydev->priv, cmd, &ret_sts); + if (ret) + phydev_err(phydev, "Invalid IPC status on IPC poll: %x\n", + ret_sts); + + mutex_unlock(&priv->ipc_lock); + + return ret; +} + +static int aeon_ipc_dbg_cmd(struct phy_device *phydev, u16 dbg_sec, + u16 dbg_cmd, u16 msg_size) +{ + u16 data[3]; + + data[0] =3D FIELD_PREP(IPC_DATA_DBG_SEC, dbg_sec) | + FIELD_PREP(IPC_DATA_DBG_CMD, dbg_cmd); + data[1] =3D msg_size; + + return aeon_ipc_send_msg(phydev, IPC_CMD_DBG, data, + sizeof(data), NULL); +} + +static int aeon_ipc_dbg_read_buf(struct phy_device *phydev, u16 *buf) +{ + struct as21xxx_priv *priv =3D phydev->priv; + u16 cmd, ret_sts; + int ret; + + cmd =3D FIELD_PREP(AEON_IPC_CMD_SIZE, 0) | + FIELD_PREP(AEON_IPC_CMD_OPCODE, IPC_CMD_READ_BUF); + + mutex_lock(&priv->ipc_lock); + + ret =3D aeon_ipc_send_cmd(phydev, phydev->priv, cmd, &ret_sts); + if (ret) + goto out; + + ret =3D aeon_ipc_get_msg_ret_data(phydev, ret_sts, buf); + +out: + mutex_unlock(&priv->ipc_lock); + + return ret; +} + +static int aeon_ipc_dbg_write_buf(struct phy_device *phydev, u8 *data, + u8 data_len) +{ + u16 msg_data[AEON_IPC_DATA_NUM_REGISTERS]; + struct as21xxx_priv *priv =3D phydev->priv; + u16 cmd, ret_sts; + int ret; + int i; + + /* Make sure we don't try to write more data than supported */ + if (data_len * 2 > AEON_IPC_DATA_MAX) + return -EINVAL; + + /* Pack u8 DBG data in u16 buffer */ + for (i =3D 0; i < data_len; i +=3D 2) { + msg_data[i] =3D data[i]; + msg_data[i] |=3D data[i + 1] << 8; + } + + ret =3D aeon_ipc_set_msg_data(phydev, msg_data, data_len * 2); + if (ret) + return ret; + + cmd =3D FIELD_PREP(AEON_IPC_CMD_SIZE, data_len) | + FIELD_PREP(AEON_IPC_CMD_OPCODE, IPC_CMD_WRITE_BUF); + + mutex_lock(&priv->ipc_lock); + + ret =3D aeon_ipc_send_cmd(phydev, priv, cmd, &ret_sts); + if (ret) + phydev_err(phydev, "failed to send IPC msg for %x: %d\n", + IPC_CMD_WRITE_BUF, ret); + + mutex_unlock(&priv->ipc_lock); + + return ret; +} + static int aeon_dpc_ra_enable(struct phy_device *phydev) { u16 data[2]; --=20 2.51.0