From nobody Mon Jun 8 14:35:33 2026 Received: from mail-wr1-f51.google.com (mail-wr1-f51.google.com [209.85.221.51]) (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 763C033291F for ; Thu, 28 May 2026 20:52:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.51 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780001571; cv=none; b=axVwRjhb5lZrEEHMJb/DsJVbCcFrmwXJgBoV8ASu0JrdmP573G2DnS/sSam5pGbLXiWQujSCrCdAxZcgLoXv/84v9oFmLr1pY43vy67CQmsugtxTNTD4F59OVo3CKNKC0BfdPt2UeSKTgIxfPq2vp5CmKomeL0MlpUmHQWUodHk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780001571; c=relaxed/simple; bh=5lXklgMxShwBwdT+Aj+Qb2oCq32nbmorVYaWfS1Wg+g=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=NyPaVixiPebFuk7uQ1539Mu2gKlV9pWmetyrq/vy5mKzNcpOopWCBd9N/VtREhUga+VqB0OtiojbEI1z8oyGwYFBgt4Bl9dVojXR3Xk/wRR+XvI/+QCqBdiuGp/ej+uiTJ3AMWp6ti7VTDFWHi2M5V6w5Oz/o4CCDf5Y+H2XjT4= 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=BpyaJpuo; arc=none smtp.client-ip=209.85.221.51 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="BpyaJpuo" Received: by mail-wr1-f51.google.com with SMTP id ffacd0b85a97d-44dd5cb0f81so9239779f8f.0 for ; Thu, 28 May 2026 13:52:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1780001569; x=1780606369; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=XojjIRDhIyxrDp1Lf41UPx11rtEM/hZDetN38j+qBos=; b=BpyaJpuoEQV46HKKD2INzzbc1N463T6OJlkeTiwDtxcyxvbG/PEzliVim5oY7YgLux dnSmSrd3MwKOlbLjCMXnJ0j7xrqp4KlLBfBinRHsg/NFJrg03GQ7+uNZPAM4X5zXMri0 u8dCvC4aVhIhmF/mVN2juI80SXrkkLz4XsDNC98loVrCSjhxoiXuSCTq57fivWEbU4ey g3LeOxGjOcvmchFt+KDPv8ZkxAOcptJXh54VZkJGV9sBocwvoljriMLr8+LLdHC297Bc aiWPBNLiDTGXfjiDcLXH0+IkrzSJwysB5T/xn9Mh4SMQu6B8YhWBSQwkEu3P5xe1R0hZ f8ZQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780001569; x=1780606369; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=XojjIRDhIyxrDp1Lf41UPx11rtEM/hZDetN38j+qBos=; b=APuuoJ5bS94dbAavvD1d8sfir/4/MkifUGlSIjuYiCskakCu0NVzNXlv7jqWRN+zrK nccWs9U+SGDEHVNOmqSqb0/IurFhQUilAEAAmPBV/OmWkEKVn5bXsNCmF96m6FUJP8is 2YhiCK/YPu3rL2Z6wIexafLaqrWjKYu952Io9Rr1kMDuSFaQUtHqvy9xNpWPDENnsmG9 GMkhvumuom7q7MTYkkwC4tmX7MXICpCNRBq3sucmmrkQmBZadwIg+HzMYiyxszP3HrAQ cpSi1ITsQLJkQARzyUpTfauqXaLRczOWkalksn7MMVwKY7JJTC44YDiXnhHk09Ulw9pl i3gA== X-Forwarded-Encrypted: i=1; AFNElJ8azRM6rpY76aSYsZWM3JdGfob6ni5gx0mPKgyEh4cOxzYrqequCL318a1uGeDpzjDXgKLWDZ4kqAJdbHE=@vger.kernel.org X-Gm-Message-State: AOJu0YxcNiARC/y2wkZ8meXOggkma0Iarf+Yzr2/vSksiP4MDLoJYSse A0hn/Fag92Ax3GyIanAFpW0CmOFIMqt6IMfUROP3zjz+3vDoHsRWMwIH X-Gm-Gg: Acq92OH00fq7+lQo8tImnNWc94cTpBYgH31eNTBXPoUnnHGzvs+cg8P8Em2je+Pd0Ew Fu42/rRv0tJYNRuZ2/HFNQyq+rzTzAT52vXCbWEVmCRtBuFPiuocTIur8KONUrQoxAbal7jaCBA +j1YouL1T+5yo8rj4Vez6a51ECCImgz6NNUu1whIe6q0aN9AISrRzrWp/uFZR1G7WgM9oEefiHj n5yIJRoaWuK0ow4+h6I4F9IsHFlEsIu8XNM+rTTkyHIUD2cVLBzft4ZhZCPE4inv5ygga0n0ayq iXe5Tb9u4HLOdq6/6lIVdoL4wuS+COfiAV8dtw29QDfpxf5bpE/wnp1E9CXHjmlN7EWriKPK1kG KVkuM1Pxc9dDfU+lUj+aZXpqbErJLOTCqqBARG6SyNWQgexi6/VFRylPbKY2lngphRqzqiee0TF r0XinZadEWn3n/V0QfEM6iM0FMGP6RwwWm5dey X-Received: by 2002:a05:6000:200f:b0:45e:89e9:348b with SMTP id ffacd0b85a97d-45ef1339797mr104379f8f.7.1780001568888; Thu, 28 May 2026 13:52:48 -0700 (PDT) Received: from builder ([2001:9e8:f104:6516:be24:11ff:fe30:5d85]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-45ee5a84e92sm7104028f8f.35.2026.05.28.13.52.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 28 May 2026 13:52:48 -0700 (PDT) From: Jonas Jelonek To: Russell King , Andrew Lunn , Heiner Kallweit , "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Maxime Chevallier Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org, =?UTF-8?q?Bj=C3=B8rn=20Mork?= , Simon Horman , Jonas Jelonek , stable@vger.kernel.org Subject: [PATCH net-next v9 1/3] net: sfp: initialize i2c_block_size at adapter configure time Date: Thu, 28 May 2026 20:52:40 +0000 Message-ID: <20260528205242.971410-2-jelonek.jonas@gmail.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20260528205242.971410-1-jelonek.jonas@gmail.com> References: <20260528205242.971410-1-jelonek.jonas@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" sfp->i2c_block_size is only assigned in sfp_sm_mod_probe(), which runs from the state machine timer after SFP_F_PRESENT has been set. Between those two points, sfp_module_eeprom() (the ethtool -m callback) gates only on SFP_F_PRESENT and can be entered with i2c_block_size still at its kzalloc'd value of 0. On a pure-I2C adapter, sfp_i2c_read() then issues an i2c_transfer() with msgs[1].len =3D 0 inside a loop that subtracts this_len from len each iteration; on adapters that succeed a zero-length read the loop never advances, spinning while holding rtnl_lock. This was previously addressed by initializing i2c_block_size in sfp_alloc() (commit 813c2dd78618), but the initialization was dropped when i2c_block_size was split from i2c_max_block_size. Initialize sfp->i2c_block_size from sfp->i2c_max_block_size in sfp_i2c_configure(), so the field is valid as soon as the adapter is known. sfp_sm_mod_probe() still reassigns it on each module insertion to recover from a per-module clamp to 1 (sfp_id_needs_byte_io). Fixes: 7662abf4db94 ("net: phy: sfp: Add support for SMBus module access") Cc: stable@vger.kernel.org Signed-off-by: Jonas Jelonek --- drivers/net/phy/sfp.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/phy/sfp.c b/drivers/net/phy/sfp.c index 7a865f69a6bd..376f7232f9ee 100644 --- a/drivers/net/phy/sfp.c +++ b/drivers/net/phy/sfp.c @@ -824,6 +824,7 @@ static int sfp_i2c_configure(struct sfp *sfp, struct i2= c_adapter *i2c) return -EINVAL; } =20 + sfp->i2c_block_size =3D sfp->i2c_max_block_size; return 0; } =20 --=20 2.51.0 From nobody Mon Jun 8 14:35:33 2026 Received: from mail-wm1-f42.google.com (mail-wm1-f42.google.com [209.85.128.42]) (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 77F442F549F for ; Thu, 28 May 2026 20:52:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.42 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780001574; cv=none; b=pvB6ypNPZfaBX4kELdCPiYnUPWI4dqZWTRNrG6xSM6tutJU/sZnYpYUwOiRKswk3XtX/oaMti4HjTRfgxUWS90yVCAtm6WcKiwlnwiulFCEdhxYu9DexQ227OVRpeNtxqLcvElWlYh72TVn4EG1ngUkZC4uERtmAUg5WnL67pWA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780001574; c=relaxed/simple; bh=1/q8glwu4s5w4FUKk4jEc8qnkNSxpoqlZxeBCfbPbdI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=VfdFAQcPOYrfXXFkNsw0eMxPhvFxwfnCW0d6dZTaKDrPrsztFMGOdxsFWwHia8NaQ9U9iyxRlsgO7MgFoyB1emF+MSBmmeX2pYtYU3IDugDXXKf1+32GiuGyeqj9OMvhyyMK1xBLfhAl/7RINtFidPmbxnA3biWOe/tSTyh/bFc= 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=CHlJ6Vo6; arc=none smtp.client-ip=209.85.128.42 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="CHlJ6Vo6" Received: by mail-wm1-f42.google.com with SMTP id 5b1f17b1804b1-4906869f0cbso52627785e9.1 for ; Thu, 28 May 2026 13:52:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1780001570; x=1780606370; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=efI/0Pq3FRsEo7Ip3A6gRAbN3ndW+5SuWmktEx7XnSs=; b=CHlJ6Vo6vL7ySZUXqEIr65KX2jCY66mmlgHnvcJU6CZurkWgSi7TEY0m0DZiwVRKP2 t/xXpVa+ADpK2LJ4n7PbYnpImI6BMpcDG4KXlS4VuOTV2Ta9Ox8+TIOyjU/ujAxmnZsF VHAQR2Png5EWHkD1zew8bBAhL4pMowA26UC5LWlLMqZcj441lPTKwJnPinQn1PPrZhGn eeHeQ+D+1rHO09rM6wKihD3smEqqO/wVXzSKbTddpOuY+CPw3560gFX87v4H7k6OvIwC s1LBCsI/L6q+HZWE2lKeGXDRVLVvQBbRpmboFMfGlawrmZ6ALULszsPpTuESIyZD9/L4 MEWQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780001570; x=1780606370; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=efI/0Pq3FRsEo7Ip3A6gRAbN3ndW+5SuWmktEx7XnSs=; b=e5jplQ719Bi7trsOrCIrjymuSCs7TM9Nvq7hpIUS2j5Exeg6iGsr5hCmHscKh+TA9A tU+ZNjIIO7OKkGFiw4AdIaibICtu/MWv7Nbyv5H52FCTaelw9XthKnePXN3JJMqkuI1q 1b5h9GB4WmTjCerU7UWjDBmCupKrQm+NkUfaQ26Wj4xok0l7vBtUC+Lv3RjkxCDLxwr2 j20w8uChhRpdeTFrbGe9NDhbI+EXmUbFGBVYAgGCvnn9N47qJ1vG27y+oOWq2lTit6aQ T2CFVn5w9SvYE+FsoRYmvLbuqNkDKgusYwZTc5HncFylpysAqOOxOMkPfT4i3MDtHVCP eHlw== X-Forwarded-Encrypted: i=1; AFNElJ+osLb73WRoh45Tuw8eIbTeWbwamr0YFX4ptKvquIqf/83VRJl4NPEGFXYcWozVgZ9eqT6Grq0QgsB6doI=@vger.kernel.org X-Gm-Message-State: AOJu0YyjikWGvNpsnxSELSQde6Cd8Hm6nfoymHcnuXsOYw2rNeOzHp2N lxZQaawwg3vTF4DHPeH9e9cX/+CGZykjPZhRaEAYIVp3bZpm+M+d4SUG X-Gm-Gg: Acq92OFa7fJ1sGkFhY7+qYMpn9Uw7lUg/2A2qsquue5Dar3tmE7QSOap05Vlq0in8Wj 50Fn/aM3NXyc6WvWRBrm729SXUEyfBmc1qt9BIAd08Xy8yh80gwF6/APQZXZoo6S4E4ZVyTVNJN P8SpA4NWj9IFCgAQn765WQ9kTABVotN8gjq6sOxNDPHI3GFc32NUzS4zMOEdrtSjdVqz4O84/vh EdaMYG8J3775imujEZQPQNFDiYcet3V7/6tK+JPBiSMdr8dp7oRnC8L5nujMevRiMJJ5plQiWVZ RCrb3oBxnilKc2qWgYGVXHJOjLyCSBEubUwyHmLKRKxPIwKXNeKCTKwlO0nx7PXubjMjO0LwP0X dSNyyGsJCsqBo/LnZ8D8Ohxj5ZquCqiUYi4syf5vhjN8SivFq/ZMzgLY6iw4+KVxJtGkaDP9Xbu rlbzoHG/sxorsQTpfmontQrTygpyKI8B+lLrsV X-Received: by 2002:a05:600c:6287:b0:48a:7676:30bc with SMTP id 5b1f17b1804b1-4909c08cd89mr1988945e9.14.1780001569686; Thu, 28 May 2026 13:52:49 -0700 (PDT) Received: from builder ([2001:9e8:f104:6516:be24:11ff:fe30:5d85]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-45ee5a84e92sm7104028f8f.35.2026.05.28.13.52.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 28 May 2026 13:52:49 -0700 (PDT) From: Jonas Jelonek To: Russell King , Andrew Lunn , Heiner Kallweit , "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Maxime Chevallier Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org, =?UTF-8?q?Bj=C3=B8rn=20Mork?= , Simon Horman , Jonas Jelonek Subject: [PATCH net-next v9 2/3] net: sfp: apply I2C adapter quirks to limit block size Date: Thu, 28 May 2026 20:52:41 +0000 Message-ID: <20260528205242.971410-3-jelonek.jonas@gmail.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20260528205242.971410-1-jelonek.jonas@gmail.com> References: <20260528205242.971410-1-jelonek.jonas@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" The SFP driver assumes all I2C adapters support reading and writing the pre-defined block size SFP_EEPROM_BLOCK_SIZE of 16 bytes. This constant was probably chosen based on good guesses and known limitations of a range of I2C adapters and SFP modules. However, I2C adapters may even support less and usually need to specify this via I2C quirks. Theoretically, such an adapter may provide full functionality but only support a read and write length of e.g. 8 bytes. Currently, the SFP driver doesn't account for that. Add handling for I2C quirks in SFP I2C configuration taking the fields max_read_len and max_write_len in struct i2c_adapter_quirks into account to further limit the maximum block size if needed. Signed-off-by: Jonas Jelonek Reviewed-by: Maxime Chevallier --- drivers/net/phy/sfp.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/net/phy/sfp.c b/drivers/net/phy/sfp.c index 376f7232f9ee..60f36cba3d83 100644 --- a/drivers/net/phy/sfp.c +++ b/drivers/net/phy/sfp.c @@ -809,21 +809,29 @@ static int sfp_smbus_byte_write(struct sfp *sfp, bool= a2, u8 dev_addr, =20 static int sfp_i2c_configure(struct sfp *sfp, struct i2c_adapter *i2c) { + size_t max_block_size; + sfp->i2c =3D i2c; =20 if (i2c_check_functionality(i2c, I2C_FUNC_I2C)) { sfp->read =3D sfp_i2c_read; sfp->write =3D sfp_i2c_write; - sfp->i2c_max_block_size =3D SFP_EEPROM_BLOCK_SIZE; + max_block_size =3D SFP_EEPROM_BLOCK_SIZE; } else if (i2c_check_functionality(i2c, I2C_FUNC_SMBUS_BYTE_DATA)) { sfp->read =3D sfp_smbus_byte_read; sfp->write =3D sfp_smbus_byte_write; - sfp->i2c_max_block_size =3D 1; + max_block_size =3D 1; } else { sfp->i2c =3D NULL; return -EINVAL; } =20 + if (i2c->quirks && i2c->quirks->max_read_len) + max_block_size =3D min(max_block_size, i2c->quirks->max_read_len); + if (i2c->quirks && i2c->quirks->max_write_len) + max_block_size =3D min(max_block_size, i2c->quirks->max_write_len); + + sfp->i2c_max_block_size =3D max_block_size; sfp->i2c_block_size =3D sfp->i2c_max_block_size; return 0; } --=20 2.51.0 From nobody Mon Jun 8 14:35:33 2026 Received: from mail-wm1-f48.google.com (mail-wm1-f48.google.com [209.85.128.48]) (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 59C34352008 for ; Thu, 28 May 2026 20:52:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.48 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780001575; cv=none; b=LKI8sAwPbat+BCEyOTFJq8tllUhYMPcEcE9GU5vfb8aeM5tqm2xEm8NV2d2ncdb8+FGDa68Yj43bY/G/D1zsZbGub8UOUSTOx8pDUK4KP+7LyvbVhFv7ZnJoUikkh4AzbRwQVdezrw5SY56EfQLsGCYF9u83qTdSzNerH0TquQQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780001575; c=relaxed/simple; bh=gYl2Q5OIz8c1hTuxPbnw6ypHy1wyYNAAdMV8txuM8r4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=L2ZEhPXBAby9ZBgzVUWZ+dhrYpul9krsqfpt8mBtfMoYYCeIpzLCFqCgj6DNlRNG0N8CCjwe6rLcDihIhuEW1J64GPgO8DiXVHb1iYXa8e7QuvB3WQ1G5Nb1Ieqc3J+JaOFs42coSjxAYHgFYBnm6jBfpg23EEDJNXQJD55lvRE= 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=c/Vklm7i; arc=none smtp.client-ip=209.85.128.48 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="c/Vklm7i" Received: by mail-wm1-f48.google.com with SMTP id 5b1f17b1804b1-49041fb8c23so55061475e9.0 for ; Thu, 28 May 2026 13:52:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1780001571; x=1780606371; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=etJjvA+lJoJ5iQ2R2eIRXhSV62QeiitQTrJwFNjFCsc=; b=c/Vklm7iYfsGfz5fMiZPPLcvkO23gAS0ITNR3BFoeYWtzlXcx4LptTt6A4RedmBfEM 5zZ3ypIhi5YuA90WWdRKDXfTwPwNcN72ZRPCUo30uNLcZcrS+OkLSbbaeKmPe7OcXqjy JR1ncWcx8H09LykmnEbaROJCWIeSjBOsJ+lL5eFqJIMIwE13IdC2EeoM+nkR+qU78eZ6 2I/SvaeHcHXQ11JFv/TAhlwvuUsUu4qfxTddk9y0XE0t5TEkJZI5WBF117wYxGj8GHq9 2FqaJiSgaAjfgThFi/BceLM/FG2lisjE4+yIMKrVIE+hXkAdWsQ8qsqMt1gL8c0LKVwT zdlQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780001571; x=1780606371; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=etJjvA+lJoJ5iQ2R2eIRXhSV62QeiitQTrJwFNjFCsc=; b=tTKbCrGNobXK8DdxnEDt3zuPB9ijrUkaqRBOo+ysnp0WozrpkBh3mD6M7hPz3MLIdU y0oSDYcx0U38JGFKdMqjWNAmxnM+uNXjLCh9TmbND56FhsEY7QjV5THRsrsXJ1yblxWf YLEvE1izrVqWS5tsLKUbjklPMP9HkOWAfIByW6GZ1/QgJdZDyp+lxLu9UEve/d2kXo+V yjTavNkaXfrxmOxP85Zr0lk3cJ9qaitT6t6kITnPJ3Rjk+qGJT5DsAwTQMzVGxg8ippB u8+wT8YGQUArhXbqtHdEtadT1DhadAqMeeKxkCycboaUQdJ2IQA8wQlm577YdgBHhkaw m50g== X-Forwarded-Encrypted: i=1; AFNElJ/z1PEHAS24Y3V8U1WTg1g6QCDjyDXmsZedSj6hqpS7epPZ6rOVYu1+ihc5pkLSpz2TMR/rr1zGkI040RY=@vger.kernel.org X-Gm-Message-State: AOJu0YzkDlZRbFuC3nPOV1FIbp7/A0N7aLc1obfCC3DSLIRV60idxGid Vlgso7ar5/+kPgXMFJJ08HbloxdSBxiatPKbiLjcPEKtaznMoLQ113Zp X-Gm-Gg: Acq92OFmys+eqNWEkf9V/NdmnbQzcTGie/UukTcgSzRHy3dXBSwt4b8H7aQl845Cc6f gybZNoTf0Qxm24aUGi/pTYkC/mOoSD9zrN3yrjQMubVBErbx23mQ3YpNHGG8bOcCNifJKpAnhmT S8g4RQoodTQFOMqNo2UGYDByaDK/c4foPQ5JeRec7G3+MrBq6Ghd6SwoVvgx2l9pe3hlAZ0wuXW qxEIH0aPGmC5ijb004GoiKZEq4AjZhBZRV0aRKRmPZtDOTka2D9khDDeDIB2b/vqNHewjOGD79Z rD+XQcpCXyVXSzxoKO1NRNCl5ErOTOl+yRofe9fMecoI/o/5MwUMk+5FonDKVZGCMjViHnTG0iC mU08BX87oD9TIB1i7RD7donM8oIfFHIFqqmjoJWOhNp38SZ1hp/MyPzaQecJN9FTSWP9DhcJB7t VW1tEiS5Jjxo9SURrfo7xfgJCk0sVzSY0ZF5ip X-Received: by 2002:a05:600c:58ce:b0:490:44eb:c1ea with SMTP id 5b1f17b1804b1-4909c0b546cmr1174425e9.24.1780001570449; Thu, 28 May 2026 13:52:50 -0700 (PDT) Received: from builder ([2001:9e8:f104:6516:be24:11ff:fe30:5d85]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-45ee5a84e92sm7104028f8f.35.2026.05.28.13.52.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 28 May 2026 13:52:50 -0700 (PDT) From: Jonas Jelonek To: Russell King , Andrew Lunn , Heiner Kallweit , "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Maxime Chevallier Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org, =?UTF-8?q?Bj=C3=B8rn=20Mork?= , Simon Horman , Jonas Jelonek Subject: [PATCH net-next v9 3/3] net: sfp: extend SMBus support Date: Thu, 28 May 2026 20:52:42 +0000 Message-ID: <20260528205242.971410-4-jelonek.jonas@gmail.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20260528205242.971410-1-jelonek.jonas@gmail.com> References: <20260528205242.971410-1-jelonek.jonas@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" Commit 7662abf4db94 ("net: phy: sfp: Add support for SMBus module access") added SMBus access for SFP modules, but limited it to single-byte transfers. As a side effect, hwmon is disabled (16-bit reads cannot be guaranteed atomic) and a warning is printed. Many SMBus-only I2C controllers in the wild support more than just byte access, and SFP cages are often wired to such controllers rather than to a full-featured I2C controller -- e.g. the SMBus controllers in the Realtek longan and mango SoCs, which advertise word access and I2C block reads. Today, they cannot drive an SFP at all without falling back to the byte-only path. Extend sfp_smbus_read()/sfp_smbus_write() so that, in addition to the existing byte access, they also use SMBus word access and SMBus I2C block access whenever the adapter advertises them. Both directions are handled in a single read and a single write helper that pick the largest supported transfer per chunk and fall back as needed. I2C-block is preferred unconditionally when available: the protocol carries any length 1..32, so it can serve every chunk -- including the 1- and 2-byte tails -- without help from word or byte access. Note that this requires I2C_FUNC_SMBUS_I2C_BLOCK, which reads a caller-specified number of bytes. This deviates from the official SMBus Block Read (length is supplied by the slave) but is widely supported by Linux I2C controllers/drivers. Capability matrix this implementation supports: - BYTE only: works (unchanged behaviour); 1-byte xfers, hwmon disabled. - BYTE + WORD: word for >=3D2-byte chunks, byte for trailing odd byte. - I2C_BLOCK present (with or without BYTE/WORD): block as the universal transport for every chunk. - WORD only (no BYTE/BLOCK): accepted with WARN_ONCE. Even-length transfers work; odd-length transfers (e.g. the 3-byte cotsworks fixup write) hit the BYTE branch which the adapter does not implement, so the xfer returns an error and the operation is aborted. No mainline I2C driver was found to advertise WORD without BYTE; the warning lets us learn about it if it ever shows up. Adapters with asymmetric R/W capabilities (e.g. only READ_I2C_BLOCK but not WRITE_I2C_BLOCK) remain functionally correct -- the per-iteration fallback uses the direction-specific bits -- but the shared i2c_max_block_size is sized by the all-bits-set check, so a transfer in the better-supported direction is not upgraded. None of the mainline I2C bus drivers surveyed during review advertise such asymmetry; promoting i2c_max_block_size to per-direction sizes can be revisited if needed. Signed-off-by: Jonas Jelonek Reviewed-by: Maxime Chevallier --- drivers/net/phy/sfp.c | 136 +++++++++++++++++++++++++++++++++--------- 1 file changed, 108 insertions(+), 28 deletions(-) diff --git a/drivers/net/phy/sfp.c b/drivers/net/phy/sfp.c index 60f36cba3d83..1725eb2151a1 100644 --- a/drivers/net/phy/sfp.c +++ b/drivers/net/phy/sfp.c @@ -14,6 +14,7 @@ #include #include #include +#include #include =20 #include "sfp.h" @@ -758,50 +759,110 @@ static int sfp_i2c_write(struct sfp *sfp, bool a2, u= 8 dev_addr, void *buf, return ret =3D=3D ARRAY_SIZE(msgs) ? len : 0; } =20 -static int sfp_smbus_byte_read(struct sfp *sfp, bool a2, u8 dev_addr, - void *buf, size_t len) +static int sfp_smbus_read(struct sfp *sfp, bool a2, u8 dev_addr, void *buf, + size_t len) { - union i2c_smbus_data smbus_data; + union i2c_smbus_data smbus_data =3D {0}; u8 bus_addr =3D a2 ? 0x51 : 0x50; + size_t this_len, transferred; + u32 functionality; u8 *data =3D buf; int ret; =20 - while (len) { - ret =3D i2c_smbus_xfer(sfp->i2c, bus_addr, 0, - I2C_SMBUS_READ, dev_addr, - I2C_SMBUS_BYTE_DATA, &smbus_data); - if (ret < 0) - return ret; + functionality =3D i2c_get_functionality(sfp->i2c); =20 - *data =3D smbus_data.byte; + while (len) { + this_len =3D min(len, sfp->i2c_block_size); + + if (functionality & I2C_FUNC_SMBUS_READ_I2C_BLOCK) { + smbus_data.block[0] =3D this_len; + ret =3D i2c_smbus_xfer(sfp->i2c, bus_addr, 0, + I2C_SMBUS_READ, dev_addr, + I2C_SMBUS_I2C_BLOCK_DATA, &smbus_data); + if (ret < 0) + return ret; + + memcpy(data, &smbus_data.block[1], this_len); + transferred =3D this_len; + } else if (this_len >=3D 2 && + (functionality & I2C_FUNC_SMBUS_READ_WORD_DATA)) { + ret =3D i2c_smbus_xfer(sfp->i2c, bus_addr, 0, + I2C_SMBUS_READ, dev_addr, + I2C_SMBUS_WORD_DATA, &smbus_data); + if (ret < 0) + return ret; + + put_unaligned_le16(smbus_data.word, data); + transferred =3D 2; + } else { + ret =3D i2c_smbus_xfer(sfp->i2c, bus_addr, 0, + I2C_SMBUS_READ, dev_addr, + I2C_SMBUS_BYTE_DATA, &smbus_data); + if (ret < 0) + return ret; + + *data =3D smbus_data.byte; + transferred =3D 1; + } =20 - len--; - data++; - dev_addr++; + data +=3D transferred; + len -=3D transferred; + dev_addr +=3D transferred; } =20 return data - (u8 *)buf; } =20 -static int sfp_smbus_byte_write(struct sfp *sfp, bool a2, u8 dev_addr, - void *buf, size_t len) +static int sfp_smbus_write(struct sfp *sfp, bool a2, u8 dev_addr, void *bu= f, + size_t len) { union i2c_smbus_data smbus_data; u8 bus_addr =3D a2 ? 0x51 : 0x50; + size_t this_len, transferred; + u32 functionality; u8 *data =3D buf; int ret; =20 + functionality =3D i2c_get_functionality(sfp->i2c); + while (len) { - smbus_data.byte =3D *data; - ret =3D i2c_smbus_xfer(sfp->i2c, bus_addr, 0, - I2C_SMBUS_WRITE, dev_addr, - I2C_SMBUS_BYTE_DATA, &smbus_data); - if (ret) - return ret; + this_len =3D min(len, sfp->i2c_block_size); + + if (functionality & I2C_FUNC_SMBUS_WRITE_I2C_BLOCK) { + smbus_data.block[0] =3D this_len; + memcpy(&smbus_data.block[1], data, this_len); + + ret =3D i2c_smbus_xfer(sfp->i2c, bus_addr, 0, + I2C_SMBUS_WRITE, dev_addr, + I2C_SMBUS_I2C_BLOCK_DATA, &smbus_data); + if (ret < 0) + return ret; + + transferred =3D this_len; + } else if (this_len >=3D 2 && + (functionality & I2C_FUNC_SMBUS_WRITE_WORD_DATA)) { + smbus_data.word =3D get_unaligned_le16(data); + ret =3D i2c_smbus_xfer(sfp->i2c, bus_addr, 0, + I2C_SMBUS_WRITE, dev_addr, + I2C_SMBUS_WORD_DATA, &smbus_data); + if (ret < 0) + return ret; + + transferred =3D 2; + } else { + smbus_data.byte =3D *data; + ret =3D i2c_smbus_xfer(sfp->i2c, bus_addr, 0, + I2C_SMBUS_WRITE, dev_addr, + I2C_SMBUS_BYTE_DATA, &smbus_data); + if (ret < 0) + return ret; + + transferred =3D 1; + } =20 - len--; - data++; - dev_addr++; + data +=3D transferred; + len -=3D transferred; + dev_addr +=3D transferred; } =20 return data - (u8 *)buf; @@ -817,10 +878,29 @@ static int sfp_i2c_configure(struct sfp *sfp, struct = i2c_adapter *i2c) sfp->read =3D sfp_i2c_read; sfp->write =3D sfp_i2c_write; max_block_size =3D SFP_EEPROM_BLOCK_SIZE; - } else if (i2c_check_functionality(i2c, I2C_FUNC_SMBUS_BYTE_DATA)) { - sfp->read =3D sfp_smbus_byte_read; - sfp->write =3D sfp_smbus_byte_write; - max_block_size =3D 1; + } else if (i2c_check_functionality(i2c, I2C_FUNC_SMBUS_BYTE_DATA) || + i2c_check_functionality(i2c, I2C_FUNC_SMBUS_I2C_BLOCK)) { + /* Either protocol alone covers any length: I2C-block carries + * 1..32 bytes per xfer, byte iterates one byte at a time. + */ + sfp->read =3D sfp_smbus_read; + sfp->write =3D sfp_smbus_write; + + if (i2c_check_functionality(i2c, I2C_FUNC_SMBUS_I2C_BLOCK)) + max_block_size =3D SFP_EEPROM_BLOCK_SIZE; + else if (i2c_check_functionality(i2c, I2C_FUNC_SMBUS_WORD_DATA)) + max_block_size =3D 2; + else + max_block_size =3D 1; + } else if (WARN_ONCE(i2c_check_functionality(i2c, I2C_FUNC_SMBUS_WORD_DAT= A), + "SMBus word-only adapter; odd-length transfers will fail\n")) { + /* Word-only: even-length xfers work; odd-length xfers fall + * to BYTE, which the adapter does not advertise and will + * likely fail. + */ + sfp->read =3D sfp_smbus_read; + sfp->write =3D sfp_smbus_write; + max_block_size =3D 2; } else { sfp->i2c =3D NULL; return -EINVAL; --=20 2.51.0