From nobody Thu Apr 16 08:38:20 2026 Received: from mail-qv1-f54.google.com (mail-qv1-f54.google.com [209.85.219.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 955E52571D7 for ; Sun, 1 Mar 2026 11:06:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.219.54 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772363176; cv=none; b=OPjfM2c9T0w9sxq4jsAG/BlMm3H3rTGsSlPb2TxlXx8vWAm6y6YrB7AulB9o3MA5Smk0hymV/B49i9LY0jFiqXg5gDU1NtJtZ/NlmRwu4cLAMUlLBKoMrlZOPsJcvYkwkt1MmOAbZK4e4t7mPn92gUJ+brV3LBIZhDsE9Piemo4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772363176; c=relaxed/simple; bh=mRH3xKEK4rDJ1na/2dFebNCA+wGDrTgkC4NvwtV1EcE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=oIifIDrLTsDO7669IUugNN9RT88XbdcFGiFIP0cteS0fiIdlbmRYa/y+25zePNEuSydwCgYN10OlcP6pjBTGytVaS7gNUyTaKVC6TnGEVhpgIG3Lj0/lpijg1j9k5/Ln7GkbNahRveuUD3lBj3TY3g35MJb7mPvx/WbQCKeM9MI= 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=KxGhjSaz; arc=none smtp.client-ip=209.85.219.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="KxGhjSaz" Received: by mail-qv1-f54.google.com with SMTP id 6a1803df08f44-896f4627dffso51266296d6.0 for ; Sun, 01 Mar 2026 03:06:15 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1772363175; x=1772967975; 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=g4/5/+DIm0PUNzsRnH2ixLLbCTuqehmznv3FgCZlvEE=; b=KxGhjSazHM01sZbaIqx1b1wk8DIcZ1Z6KUsEHRXNsew43WR7MA95XF++3Pvqpkc48E XhZSIuDgVRRC1LkKkX0c4RgtTrBFYI4fFtQM2IpQJO7jnzezPOrtC6p0p2dr9tsTvVxx ap96MYg7pV0dcTk974M1qUO+FaWqk5oEv92za2kglMt0Bu7408vD73arbkYNU27mmGQa T66KOhwR3x+MiE8gl1OZo4mLbcex8J+oHS/J6AVWpGk6KSaWio1AY5D9a703lQIqW3My I+59+35P8OKXQuDsIcA7XWfH7v1fZP1RvPioudG+NhUw3sZWuETEwUrWYzPL+hDRlGrM pmag== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772363175; x=1772967975; 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=g4/5/+DIm0PUNzsRnH2ixLLbCTuqehmznv3FgCZlvEE=; b=kTwLxwgTbE6Nqb/P/+zqBdJJViJJ0+jnjTSgAVYaUeJNHsfwwN7sFSP2DdT1zQ0uE+ eWVoH9p6cTu40COLUhsBAlTb8TLy92Ao5aI5Da3UIyK9RPEcSJ7fkPt1lZJPbpZYpN3Q nSLnlfIvvTcW7uU7AUDnz3li6IFpo6Jxav6qGvGMIHhAsDMmZ+VX8s1SVgAnY9wppoh9 FfG4he/ys7cffofJjjh0lRxxtvnqjfenLg1PQBqvPn7F4zYY2AavAh73zvDVAiwT/LLK TwcgRWAKoQwFNnzlj1v0GzeHiGXiUjbMFP5NlXaZXFzBbRKONzA7A2zWSXGdL2je0Qr6 ocBA== X-Forwarded-Encrypted: i=1; AJvYcCXeoFkxNUYQE9nQ6zC6Rrl7y3c8S3kXBzLt3/nE17CxM6nUUaiECnVGkj8tKD9dA7IJZlj2viOh+v0iKlw=@vger.kernel.org X-Gm-Message-State: AOJu0YzUGyhsfEHPVWykdDMzbCkgpP8/Yha14YPO5tSn8pl5n6HHOBBZ KaKkzg1ePm29uHi4hbpF/azdo0KAqPBNzQe+aU23mj3uGmYGm1uNK7l7 X-Gm-Gg: ATEYQzzeTDxabOl97zejrhNuoZ7KeRd5nx5C3QON696xH3Z+zTr8uvgzm3/joCTfo2u PO0GGARnCBTrR3TuECVOYu9nM0uYEp0Z7ekdvWVoY78yT0Sv/jNnNxnbWChkJDTluhnT0UAPbRY cQAwJd5rVYhgXtQ9xFa7MlzAk+9tVn/3sAhb7E2sOnoMhxzYW9hbCwL8nFcoXXVrsmpX0fZxSWK PRGcuZ2k+wjOR3gFGIQwAePXvTWx/MPnetOVukGI1EDmc7LWRN8QcKknxSTrLNq+LvZ39yb7/0O Tcko9iX9dbBjMPfavYeVsqefVxe54KaiXvvBU39mp4gSB7DksNTuJtHEEumClIMtGLaIpC512A5 mPcr1JapuzHZx+EZXk3E8OE4p50pMaot6gHzeiYX3wLd9XEshbwl2i85iF8cyp/yT9LPFyYeB4W EESvHKyKA0VThW7UCqk+gZpz9bRbauKLhLD/Ek0ZyvZIQxtLbamYpkVO/QMWaULGYiT56TnKwGb RpFb05EeHknEeu6 X-Received: by 2002:a05:6214:258d:b0:87c:2967:fd32 with SMTP id 6a1803df08f44-899d1db6789mr128135196d6.22.1772363174553; Sun, 01 Mar 2026 03:06:14 -0800 (PST) Received: from PF5YBGDS.localdomain (70.15.25.19.res-cmts.sm3.ptd.net. [70.15.25.19]) by smtp.gmail.com with ESMTPSA id 6a1803df08f44-899c716caebsm83888876d6.15.2026.03.01.03.06.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 01 Mar 2026 03:06:14 -0800 (PST) From: mike.marciniszyn@gmail.com To: Alexander Duyck , Jakub Kicinski , kernel-team@meta.com, Andrew Lunn , "David S. Miller" , Eric Dumazet , Paolo Abeni , Simon Horman , Russell King , Jacob Keller , Lee Trager , Mohsin Bashir , Dan Carpenter , Pei Xiao , Stanislav Fomichev , Kuniyuki Iwashima , Samiullah Khawaja , Hangbin Liu Cc: mike.marciniszyn@gmail.com, netdev@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH net-next v2.2 1/5] net: export netif_open for self_test usage Date: Sun, 1 Mar 2026 06:06:02 -0500 Message-ID: <20260301110606.3739-2-mike.marciniszyn@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260301110606.3739-1-mike.marciniszyn@gmail.com> References: <20260301110606.3739-1-mike.marciniszyn@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" From: "Mike Marciniszyn (Meta)" dev_open() already is exported, but drivers which use the netdev instance lock need to use netif_open() instead. netif_close() is also already exported [1] so this completes the pairing. This export is required for the following fbnic self tests to avoid calling ndo_stop() and ndo_open() in favor of the more appropriate netif_open() and netif_close() that notifies any listeners that the interface went down to test and is now coming back up. Link: https://patch.msgid.link/20250309215851.2003708-1-sdf@fomichev.me [1] Signed-off-by: Mike Marciniszyn (Meta) --- v2 - no changes net/core/dev.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/core/dev.c b/net/core/dev.c index 43de5af0d6ec..d1d5694d1ff0 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -1724,6 +1724,7 @@ int netif_open(struct net_device *dev, struct netlink= _ext_ack *extack) return ret; } +EXPORT_SYMBOL(netif_open); static void __dev_close_many(struct list_head *head) { -- 2.43.0 From nobody Thu Apr 16 08:38:20 2026 Received: from mail-qk1-f169.google.com (mail-qk1-f169.google.com [209.85.222.169]) (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 0274E2FE05B for ; Sun, 1 Mar 2026 11:06:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.222.169 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772363178; cv=none; b=GlNOTlHZY02UZD0VnrFaan+hyRYS9AhT7mq7O2/8k7ypBoxF6F3MLvGqEyjvFxHPG8tiHp99ayOwcJM9I2ct5FOLPol2DBSKtX97xtFSg/CpBqUC3mh6L3b712IePV0twsYHpT/KR0EP3GwJXdrHkVv/DiTK84Zr6aJDNgh8TFo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772363178; c=relaxed/simple; bh=s0OEadwKsZ5uB72903eG5RUc45bWVph/h/bYOTTGRO0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=iPM+uv14i9QOT0IDGJN0upR2qYp91ab9d/uDcNvcnEf/cFLXZMbkP4w9OirmnERYascNlMeB7iSkV1xCCSeLYUmu1c8YwodRuVeHZ7iv2s7YjdRpkCOfMPLp8KVb1VVboJTcHszEiHeG90By9mtRW9xRfO8jNllLw0hDnQA5LU4= 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=SwktBchL; arc=none smtp.client-ip=209.85.222.169 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="SwktBchL" Received: by mail-qk1-f169.google.com with SMTP id af79cd13be357-8ca01dc7d40so378192485a.1 for ; Sun, 01 Mar 2026 03:06:16 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1772363176; x=1772967976; 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=ZwG8pm1dGdxVJroX0vDelpeAdI8P+haKbzJ+FGu2QUU=; b=SwktBchLd0pJgIbEVxytKjgDvqS5byduilKNrFRS/pts2D5HCM6Nj7OdgJ+YeDyROL 5Gjg0ZkjTySUnVz+R8HIlY3CA6LUQLomV9JZyqPDj0dRM3JO/w8G3eKLesw4qtXTYjlf DHYjZETyU6F0dq+eFt3XqDQB3jHu8c1rShxOk99DgvunU66qx15dm7gi9EUY5se8d6Hg VbxzmcMC0PzmPEFEDIgiwS/4lAIolNgL1Q9QC9j3hb7ctq00PVyH02YUGJKrXjLfRsqT bEr0HorpKK+28TJooznQ6IKo+gAgPUCpvvik5IG4uoWMYjc/4qRBss8LNL8WZ8+uA75t Q2ng== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772363176; x=1772967976; 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=ZwG8pm1dGdxVJroX0vDelpeAdI8P+haKbzJ+FGu2QUU=; b=usGjvghcbeI7xMN0S4gAK2+NRwG723TJlWlBNls3Rv6Lc45XZSs7ViZK6GxI39V3Be P14Veybfe1l/t0zUx+C4O+90QVIVXLIjr6u5X6d3vVsNKwspw/ZYaWBW3ZN0/5Ev3KXl d2lE2EOrCo3lft1ISzdUNo3HwZIIiPklxqSEfEpWHQCW8RAuqyWcJX5R4oj/lzzYMDz7 vEVzlNY+EbxjdAryEU0FV9JDyuHna+OCG3WYDXiigNym2sK8FyCondDCVpe3RpIaW4Sb Avta8vLSZyOX4Ge5SvQp4M2wu8+kV1Y5fjRvp+fvtEWXWtcOhrGsCJV/Um834wVI9PXg KdrQ== X-Forwarded-Encrypted: i=1; AJvYcCUokqmlKU4C+WcbIoP8N8nnwUJ1dWiD97P0+d/Q4x1T4E4J8LfR8HpAc2Ma1EWDpsU/PVS6NSRxSRR2/wY=@vger.kernel.org X-Gm-Message-State: AOJu0Yz9EKGocFt3oSNAgV47tXer6IGXs9qVsYheYndRHZozSORvc3SU OOWj/LJCXXoZdHcCiIBqQWom5zF0Qa0HnklD997Ifz2xTWRVkA88H5It X-Gm-Gg: ATEYQzwQSXKE0lFARF07yPMdGDJ0teNsrlSIn/VMhRhtiN9Mj3/5H39VgRnojdzIEnB N3CTJ8mBNcVR5pgptPqu0t8o1Js5J2BU4U6kh53ZHShkkSZ/A3zlQtt7o5bmJlqJhCUoBBWP5UZ lQWAYA88/a7pkrfIFqS6khXlds+AJD35UW+yVVg05JiugGUnNhbGOmuEQFZ0vB6ldVvrBbQoKG3 Ap19ObCivqmOezpvoZc2yfVkBlQZkC8MNynjitQ8ABbC8n3lmYXGNlmF3XxX8eavKJ3ut4WgI3z Acm44x+FnkYb0EkDoMcnKa1QnB3pCHEOmKfZ55BS5lmpcqRIrKH4ZsxNO/xb//cHMyivEqv3uZ0 O3nBfpfUoof7polXKmkYh1ZmTI8myVbcazjBJK84ddzIYL9fsNNgeYpNHSY7HSA8wap+VJNZMo1 KGRlek9klwavyhh9b3WadPgZsUJLBjUs9C8OXTSKFg6BXhRBGfGpvy/NzkHq8QH07v7ZKB3Pazy MzDpSY3y8u1nmNN X-Received: by 2002:a05:620a:298d:b0:8cb:4b07:c42f with SMTP id af79cd13be357-8cbc8f673c3mr958439085a.82.1772363175751; Sun, 01 Mar 2026 03:06:15 -0800 (PST) Received: from PF5YBGDS.localdomain (70.15.25.19.res-cmts.sm3.ptd.net. [70.15.25.19]) by smtp.gmail.com with ESMTPSA id 6a1803df08f44-899c716caebsm83888876d6.15.2026.03.01.03.06.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 01 Mar 2026 03:06:15 -0800 (PST) From: mike.marciniszyn@gmail.com To: Alexander Duyck , Jakub Kicinski , kernel-team@meta.com, Andrew Lunn , "David S. Miller" , Eric Dumazet , Paolo Abeni , Simon Horman , Russell King , Jacob Keller , Lee Trager , Mohsin Bashir , Dan Carpenter , Pei Xiao , Stanislav Fomichev , Kuniyuki Iwashima , Samiullah Khawaja , Hangbin Liu Cc: mike.marciniszyn@gmail.com, netdev@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH net-next v2.2 2/5] eth fbnic: Add register self test Date: Sun, 1 Mar 2026 06:06:03 -0500 Message-ID: <20260301110606.3739-3-mike.marciniszyn@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260301110606.3739-1-mike.marciniszyn@gmail.com> References: <20260301110606.3739-1-mike.marciniszyn@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" From: "Mike Marciniszyn (Meta)" The register test will be used to verify hardware is behaving as expected. The test itself will have us writing to registers that should have no side effects due to us resetting after the test has been completed. While the test is being run the interface should be offline. This patch counts on the first patch of this series to export netif_open() and also ensures that the half close calls netif_close() to avoid deadlock. Signed-off-by: Mike Marciniszyn (Meta) --- v2 - add enum for test return codes - place forward of struct fbnic_dev after include with a blank line drivers/net/ethernet/meta/fbnic/fbnic.h | 18 +++ drivers/net/ethernet/meta/fbnic/fbnic_csr.c | 128 ++++++++++++++++++ drivers/net/ethernet/meta/fbnic/fbnic_csr.h | 19 +++ .../net/ethernet/meta/fbnic/fbnic_ethtool.c | 50 +++++++ 3 files changed, 197 insertions(+) diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_csr.c b/drivers/net/ethe= rnet/meta/fbnic/fbnic_csr.c index d9c0dc1c2af9..dc62d623e37c 100644 --- a/drivers/net/ethernet/meta/fbnic/fbnic_csr.c +++ b/drivers/net/ethernet/meta/fbnic/fbnic_csr.c @@ -147,3 +147,131 @@ int fbnic_csr_regs_len(struct fbnic_dev *fbd) return len; } + +/* CSR register test data + * + * The register test will be used to verify hardware is behaving as expect= ed. + * + * The test itself will have us writing to registers that should have no + * side effects due to us resetting after the test has been completed. + * While the test is being run the interface should be offline. + */ +struct fbnic_csr_reg_test_data { + int reg; + u16 reg_offset; + u8 array_len; + u32 read; + u32 write; +}; + +#define FBNIC_QUEUE_REG_TEST(_name, _read, _write) { \ + .reg =3D FBNIC_QUEUE(0) + FBNIC_QUEUE_##_name, \ + .reg_offset =3D FBNIC_QUEUE_STRIDE, \ + .array_len =3D 64, \ + .read =3D _read, \ + .write =3D _write \ +} + +static const struct fbnic_csr_reg_test_data pattern_test[] =3D { + FBNIC_QUEUE_REG_TEST(TWQ0_CTL, FBNIC_QUEUE_TWQ_CTL_RESET, + FBNIC_QUEUE_TWQ_CTL_RESET), + FBNIC_QUEUE_REG_TEST(TWQ0_PTRS, 0, ~0), + FBNIC_QUEUE_REG_TEST(TWQ0_SIZE, FBNIC_QUEUE_TWQ_SIZE_MASK, ~0), + FBNIC_QUEUE_REG_TEST(TWQ0_BAL, FBNIC_QUEUE_BAL_MASK, ~0), + FBNIC_QUEUE_REG_TEST(TWQ0_BAH, ~0, ~0), + FBNIC_QUEUE_REG_TEST(TWQ1_CTL, FBNIC_QUEUE_TWQ_CTL_RESET, + FBNIC_QUEUE_TWQ_CTL_RESET), + FBNIC_QUEUE_REG_TEST(TWQ1_PTRS, 0, ~0), + FBNIC_QUEUE_REG_TEST(TWQ1_SIZE, FBNIC_QUEUE_TWQ_SIZE_MASK, ~0), + FBNIC_QUEUE_REG_TEST(TWQ1_BAL, FBNIC_QUEUE_BAL_MASK, ~0), + FBNIC_QUEUE_REG_TEST(TWQ1_BAH, ~0, ~0), + FBNIC_QUEUE_REG_TEST(TCQ_CTL, FBNIC_QUEUE_TCQ_CTL_RESET, + FBNIC_QUEUE_TCQ_CTL_RESET), + FBNIC_QUEUE_REG_TEST(TCQ_PTRS, 0, ~0), + FBNIC_QUEUE_REG_TEST(TCQ_SIZE, FBNIC_QUEUE_TCQ_SIZE_MASK, ~0), + FBNIC_QUEUE_REG_TEST(TCQ_BAL, FBNIC_QUEUE_BAL_MASK, ~0), + FBNIC_QUEUE_REG_TEST(TCQ_BAH, ~0, ~0), + FBNIC_QUEUE_REG_TEST(RCQ_CTL, FBNIC_QUEUE_RCQ_CTL_RESET, + FBNIC_QUEUE_RCQ_CTL_RESET), + FBNIC_QUEUE_REG_TEST(RCQ_PTRS, 0, ~0), + FBNIC_QUEUE_REG_TEST(RCQ_SIZE, FBNIC_QUEUE_RCQ_SIZE_MASK, ~0), + FBNIC_QUEUE_REG_TEST(RCQ_BAL, FBNIC_QUEUE_BAL_MASK, ~0), + FBNIC_QUEUE_REG_TEST(RCQ_BAH, ~0, ~0), + FBNIC_QUEUE_REG_TEST(BDQ_CTL, FBNIC_QUEUE_BDQ_CTL_RESET, + FBNIC_QUEUE_BDQ_CTL_RESET), + FBNIC_QUEUE_REG_TEST(BDQ_HPQ_PTRS, 0, ~0), + FBNIC_QUEUE_REG_TEST(BDQ_HPQ_SIZE, FBNIC_QUEUE_BDQ_SIZE_MASK, ~0), + FBNIC_QUEUE_REG_TEST(BDQ_HPQ_BAL, FBNIC_QUEUE_BAL_MASK, ~0), + FBNIC_QUEUE_REG_TEST(BDQ_HPQ_BAH, ~0, ~0), + FBNIC_QUEUE_REG_TEST(BDQ_PPQ_PTRS, 0, ~0), + FBNIC_QUEUE_REG_TEST(BDQ_PPQ_SIZE, FBNIC_QUEUE_BDQ_SIZE_MASK, ~0), + FBNIC_QUEUE_REG_TEST(BDQ_PPQ_BAL, FBNIC_QUEUE_BAL_MASK, ~0), + FBNIC_QUEUE_REG_TEST(BDQ_PPQ_BAH, ~0, ~0), +}; + +static enum fbnic_reg_self_test_codes +fbnic_csr_reg_pattern_test(struct fbnic_dev *fbd, int index, + const struct fbnic_csr_reg_test_data *test_data) +{ + static const u32 pattern[] =3D { ~0, 0x5A5A5A5A, 0xA5A5A5A5, 0}; + enum fbnic_reg_self_test_codes reg; + int i; + + reg =3D test_data->reg + test_data->reg_offset * index; + for (i =3D 0; i < ARRAY_SIZE(pattern); i++) { + u32 val =3D pattern[i] & test_data->write; + u32 result; + + wr32(fbd, reg, val); + result =3D rd32(fbd, reg); + val &=3D test_data->read; + + if (result =3D=3D val) + continue; + + dev_err(fbd->dev, + "%s: reg 0x%06X failed, expected 0x%08X received 0x%08X\n", + __func__, reg, val, result); + + /* Note that FBNIC_INTR_STATUS(0) could be tested and fail + * and the result would not be reported since the register + * offset is 0. However as that register isn't included in + * the register test that isn't an issue. + */ + return reg; + } + + return FBNIC_REG_TEST_SUCCESS; +} + +/** + * fbnic_csr_regs_test() - Verify behavior of NIC registers + * @fbd: device to test + * + * This function is meant to test the bit values of various registers in + * the NIC device. Specifically this test will verify which bits are + * writable and which ones are not. It will write varying patterns of bits + * to the registers testing for sticky bits, or bits that are writable but + * should not be. + * + * Return: FBNIC_REG_TEST_SUCCESS on success, register number on failure + **/ +enum fbnic_reg_self_test_codes fbnic_csr_regs_test(struct fbnic_dev *fbd) +{ + const struct fbnic_csr_reg_test_data *test_data; + + for (test_data =3D pattern_test; + test_data < pattern_test + ARRAY_SIZE(pattern_test); test_data++) { + u32 i; + + for (i =3D 0; i < test_data->array_len; i++) { + enum fbnic_reg_self_test_codes reg =3D + fbnic_csr_reg_pattern_test(fbd, i, test_data); + + if (reg) + return reg; + } + } + + return FBNIC_REG_TEST_SUCCESS; +} diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_csr.h b/drivers/net/ethe= rnet/meta/fbnic/fbnic_csr.h index b717db879cd3..7cfb42067327 100644 --- a/drivers/net/ethernet/meta/fbnic/fbnic_csr.h +++ b/drivers/net/ethernet/meta/fbnic/fbnic_csr.h @@ -6,6 +6,8 @@ #include +struct fbnic_dev; + #define CSR_BIT(nr) (1u << (nr)) #define CSR_GENMASK(h, l) GENMASK(h, l) @@ -1210,4 +1212,21 @@ enum{ FBNIC_CSR_VERSION_V1_0_ASIC =3D 1, }; +/** + * enum fbnic_reg_self_test_codes - return codes from self test routines + * + * This is the code that is returned from the register self test + * routines. + * + * The test either returns success or the register number + * that failed during the test. + * + * @FBNIC_REG_TEST_SUCCESS: no errors + */ +enum fbnic_reg_self_test_codes { + FBNIC_REG_TEST_SUCCESS =3D 0, +}; + +enum fbnic_reg_self_test_codes fbnic_csr_regs_test(struct fbnic_dev *fbd); + #endif /* _FBNIC_CSR_H_ */ diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c b/drivers/net/= ethernet/meta/fbnic/fbnic_ethtool.c index 11745a2d8a44..2e882dbd408d 100644 --- a/drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c +++ b/drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c @@ -126,6 +126,16 @@ static const struct fbnic_stat fbnic_gstrings_xdp_stat= s[] =3D { #define FBNIC_STATS_LEN \ (FBNIC_HW_STATS_LEN + FBNIC_XDP_STATS_LEN * FBNIC_MAX_XDPQS) +enum fbnic_self_test_results { + TEST_REG =3D 0, +}; + +static const char fbnic_gstrings_self_test[][ETH_GSTRING_LEN] =3D { + [TEST_REG] =3D "Register test (offline)", +}; + +#define FBNIC_TEST_LEN ARRAY_SIZE(fbnic_gstrings_self_test) + static void fbnic_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvin= fo) { @@ -475,6 +485,10 @@ static void fbnic_get_strings(struct net_device *dev, = u32 sset, u8 *data) for (i =3D 0; i < FBNIC_MAX_XDPQS; i++) fbnic_get_xdp_queue_strings(&data, i); break; + case ETH_SS_TEST: + memcpy(data, fbnic_gstrings_self_test, + sizeof(fbnic_gstrings_self_test)); + break; } } @@ -566,6 +580,8 @@ static int fbnic_get_sset_count(struct net_device *dev,= int sset) switch (sset) { case ETH_SS_STATS: return FBNIC_STATS_LEN; + case ETH_SS_TEST: + return FBNIC_TEST_LEN; default: return -EOPNOTSUPP; } @@ -1475,6 +1491,39 @@ fbnic_remove_rxfh_context(struct net_device *netdev, return 0; } +static int fbnic_ethtool_regs_test(struct net_device *netdev, u64 *data) +{ + struct fbnic_net *fbn =3D netdev_priv(netdev); + struct fbnic_dev *fbd =3D fbn->fbd; + + *data =3D fbnic_csr_regs_test(fbd); + + return !!*data; +} + +static void fbnic_self_test(struct net_device *netdev, + struct ethtool_test *eth_test, u64 *data) +{ + bool if_running =3D netif_running(netdev); + + if (!(eth_test->flags & ETH_TEST_FL_OFFLINE)) { + data[TEST_REG] =3D 0; + return; + } + + if (if_running) + netif_close(netdev); + + if (fbnic_ethtool_regs_test(netdev, &data[TEST_REG])) + eth_test->flags |=3D ETH_TEST_FL_FAILED; + + if (if_running && netif_open(netdev, NULL)) { + netdev_err(netdev, + "Failed to re-initialize hardware following test\n"); + eth_test->flags |=3D ETH_TEST_FL_FAILED; + } +} + static void fbnic_get_channels(struct net_device *netdev, struct ethtool_channels *ch) { @@ -1893,6 +1942,7 @@ static const struct ethtool_ops fbnic_ethtool_ops =3D= { .get_pause_stats =3D fbnic_get_pause_stats, .get_pauseparam =3D fbnic_phylink_get_pauseparam, .set_pauseparam =3D fbnic_phylink_set_pauseparam, + .self_test =3D fbnic_self_test, .get_strings =3D fbnic_get_strings, .get_ethtool_stats =3D fbnic_get_ethtool_stats, .get_sset_count =3D fbnic_get_sset_count, -- 2.43.0 From nobody Thu Apr 16 08:38:20 2026 Received: from mail-qv1-f50.google.com (mail-qv1-f50.google.com [209.85.219.50]) (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 7F2F82E889C for ; Sun, 1 Mar 2026 11:06:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.219.50 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772363182; cv=none; b=bpTORBr6lADCcAi3Yw58NHzITUDDnf16LOqKU/iLPRNUgUyG7AQRHCL5/TjURRSfg5xAC/qK5KU6qreXXJSMyGocWpld8tYEFA179Z9Rc5tiqtdfxpW0mhiz5hd28ZpBjs6SYkdi5tPWzmJd1jGNGBpZE3T20AO1PNvRUZLthA4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772363182; c=relaxed/simple; bh=Gj06bO0OMwWVmneVnC7DfJp5XBDMxWz1rQJf8bYBpZg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=gV8SPUxuj8IEtBiqXCQuxpju003i/si1wbajOUkayU7vpOLgOqtJ9s/+nlwVZJx/PhApKHFL13cNvyPv97D7lzt1bxDymMzCMs7tfGRhn+Rn9Ej8fOwcxkYTvasaENyrGI7riSOOrdD+DTka6i4+PnOlidJdov4I9WLx0iz5t3E= 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=a4dAbl8i; arc=none smtp.client-ip=209.85.219.50 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="a4dAbl8i" Received: by mail-qv1-f50.google.com with SMTP id 6a1803df08f44-899a5db525cso31773466d6.3 for ; Sun, 01 Mar 2026 03:06:19 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1772363178; x=1772967978; 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=O3DQslWRXY0aGN4VEznJUuz1rJrCKbc4YikrhGTaWls=; b=a4dAbl8iw2ii1Yhz/POxwQNoC8D19Abdv6MZ1d1KBxKInnAxIsqZBzFvkgSarDlLkk JdgGyHD7KOvEZDFGuG7UK4Eqo4gf42yiV5JkeB42hVaebCcs/PhxKoiVjj8FvsGHoXI3 jQnWEvhdzBlCfoZHPH5bOJDoYftlQ72omCKTAWrF9+42A3DEASgYdwgxSFEtxZH07NE0 BoR9eupP82th9JYQkK8L7svjqWTkKmDzostC1fOwgPHBb2fCRAYzwmyUDcMJu5aMcilP 6Iurql9TSqPyckjKjE0LTxrxvb+6yK4aidY6CUX7bKzX/gKgtpXM92CaSbiNyqgwi4TK 1vSA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772363178; x=1772967978; 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=O3DQslWRXY0aGN4VEznJUuz1rJrCKbc4YikrhGTaWls=; b=MIT4UnEAafxHlpu9wTm5bMEnie3RC8DdZFWwhwCERbb5kChaGbJD0E9bokoQngciF/ rIJT5lGSQdT45iXPgYmufvz4yBdeUZyq5JlH/sn9zUEJ8dHRaMJvOv4rdZilvXB5zBm6 rWW3JSsxgM+okRQfGWCZp96ym0MsMgFBynZUsHyACxItqHkiQXJvEKKnIr3N2J/nByhS Fo9LEHvxJeGv8YrL7JsvaXwLJEi1aOTHcF9ChgVDQ2TMrDlqBsya9TKhvsK9OoqSiG/P otaFiGgibjUthKVfb2rpPlUfwwB/xkbkHeBAKQMQPv6syIOV7hD/jcXWKE71eTaONTZA uDtw== X-Forwarded-Encrypted: i=1; AJvYcCWxmS0Xfcg/Zo3nvUzpTxOj4jR3m9bbwBpzxp0gX6MlMsvRSCCZv06RRhi/A2S9m3vV8Qbv+oIpTCnFLFY=@vger.kernel.org X-Gm-Message-State: AOJu0Yz/cD9wg0iDRr5FM4Ba2nqP/2b1FH6uMVuyWaO7yCay9BnATshL fI69p3mjBlp+ysMAHIsanmspPuNk0tdsv6Rhi1R5uDco579xCsksNC57 X-Gm-Gg: ATEYQzyLhzRsTY+OODNTxo2Qr1m1cJkvHYo5zTk4ZPAwaWyyKap+aIXBEBKdhDM9kjh 9cz4YwhVt4iJN39gU/uQrEkgTIAfRcyq8uCqqJQnzz6QhJ1FezP9RCrjofghWzFDssFNCmfr/eO Lx53fSdSpTAQG/5D2KVodnlOYEa5U9TGcj/bNTXRb4NQGg8PsR9AjmS8QOW0/SAPsXPf4HjgliQ aQMm7YCpQLopL68Sg/ZzaL77p1Xvgln+GUiat0ttw8DmO9RwPYWDPi/qrdCnjSnm7E3Mhfsoe8C uygwk0cGP6oHrIhVErBwP7V7hL8J8LDOCgJbY/epzZ5/Vqa18c1K31A3PG0Wog79uAcr11w/Q0F z0d2S3K74a6ruv1D4tzDbZPA2F9kTr2dTVYU/KuzWrzT4iGrvH+yR0q9yALQyt90p3GTEbZQdx5 iNBwyZh2STqC2lxvNbNq7FI8VuvnFSLgxDIpZ3jW9BNoapYjdUi5YO5aXLFYN5srqBzHbaknf0a nx0XTIDOAWS2brk X-Received: by 2002:a05:6214:e65:b0:899:f78e:d73a with SMTP id 6a1803df08f44-899f78ede73mr8283726d6.20.1772363178320; Sun, 01 Mar 2026 03:06:18 -0800 (PST) Received: from PF5YBGDS.localdomain (70.15.25.19.res-cmts.sm3.ptd.net. [70.15.25.19]) by smtp.gmail.com with ESMTPSA id 6a1803df08f44-899c716caebsm83888876d6.15.2026.03.01.03.06.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 01 Mar 2026 03:06:17 -0800 (PST) From: mike.marciniszyn@gmail.com To: Alexander Duyck , Jakub Kicinski , kernel-team@meta.com, Andrew Lunn , "David S. Miller" , Eric Dumazet , Paolo Abeni , Simon Horman , Russell King , Jacob Keller , Lee Trager , Mohsin Bashir , Dan Carpenter , Pei Xiao , Stanislav Fomichev , Kuniyuki Iwashima , Samiullah Khawaja , Hangbin Liu Cc: mike.marciniszyn@gmail.com, netdev@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH net-next v2.2 3/5] eth fbnic: Add msix self test Date: Sun, 1 Mar 2026 06:06:04 -0500 Message-ID: <20260301110606.3739-4-mike.marciniszyn@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260301110606.3739-1-mike.marciniszyn@gmail.com> References: <20260301110606.3739-1-mike.marciniszyn@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" From: "Mike Marciniszyn (Meta)" This function is meant to test the global interrupt registers and the PCIe IP MSI-X functionality. It essentially goes through and tests various combinations of the set, clear, and mask bits in order to verify the behavior is as we expect it to be from the driver. Signed-off-by: Mike Marciniszyn (Meta) --- v2 - add enum for test return codes drivers/net/ethernet/meta/fbnic/fbnic.h | 18 ++ .../net/ethernet/meta/fbnic/fbnic_ethtool.c | 28 ++++ drivers/net/ethernet/meta/fbnic/fbnic_irq.c | 154 ++++++++++++++++++ 3 files changed, 212 insertions(+) diff --git a/drivers/net/ethernet/meta/fbnic/fbnic.h b/drivers/net/ethernet= /meta/fbnic/fbnic.h index 779a083b9215..092fa9ad93d0 100644 --- a/drivers/net/ethernet/meta/fbnic/fbnic.h +++ b/drivers/net/ethernet/meta/fbnic/fbnic.h @@ -194,6 +194,36 @@ void fbnic_synchronize_irq(struct fbnic_dev *fbd, int = nr); int fbnic_request_irq(struct fbnic_dev *dev, int nr, irq_handler_t handler, unsigned long flags, const char *name, void *data); void fbnic_free_irq(struct fbnic_dev *dev, int nr, void *data); + +/** + * enum fbnic_msix_self_test_codes - return codes from self test routines + * + * These are the codes returned from the self test routines and + * stored in the test result array indexed by the specific + * test name. + * + * @FBNIC_TEST_MSIX_SUCCESS: no errors + * @FBNIC_TEST_MSIX_NOMEM: allocation failure + * @FBNIC_TEST_MSIX_IRQ_REQ_FAIL: IRQ request failure + * @FBNIC_TEST_MSIX_MASK: masking failed to prevent IRQ + * @FBNIC_TEST_MSIX_UNMASK: unmasking failure w/ sw status set + * @FBNIC_TEST_MSIX_IRQ_CLEAR: interrupt when clearing mask + * @FBNIC_TEST_MSIX_NO_INTERRUPT: no interrupt when not masked + * @FBNIC_TEST_MSIX_NO_CLEAR_OR_MASK: status not cleared, or mask not set + */ +enum fbnic_msix_self_test_codes { + FBNIC_TEST_MSIX_SUCCESS =3D 0, + FBNIC_TEST_MSIX_NOMEM =3D 5, + FBNIC_TEST_MSIX_IRQ_REQ_FAIL =3D 10, + FBNIC_TEST_MSIX_MASK =3D 20, + FBNIC_TEST_MSIX_UNMASK =3D 30, + FBNIC_TEST_MSIX_IRQ_CLEAR =3D 40, + FBNIC_TEST_MSIX_NO_INTERRUPT =3D 50, + FBNIC_TEST_MSIX_NO_CLEAR_OR_MASK =3D 60, +}; + +enum fbnic_msix_self_test_codes fbnic_msix_test(struct fbnic_dev *fbd); + void fbnic_free_irqs(struct fbnic_dev *fbd); int fbnic_alloc_irqs(struct fbnic_dev *fbd); diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c b/drivers/net/= ethernet/meta/fbnic/fbnic_ethtool.c index 2e882dbd408d..b0c8d1b069e2 100644 --- a/drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c +++ b/drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c @@ -128,10 +128,12 @@ static const struct fbnic_stat fbnic_gstrings_xdp_sta= ts[] =3D { enum fbnic_self_test_results { TEST_REG =3D 0, + TEST_MSIX, }; static const char fbnic_gstrings_self_test[][ETH_GSTRING_LEN] =3D { [TEST_REG] =3D "Register test (offline)", + [TEST_MSIX] =3D "MSI-X Interrupt test (offline)", }; #define FBNIC_TEST_LEN ARRAY_SIZE(fbnic_gstrings_self_test) @@ -1501,6 +1503,28 @@ static int fbnic_ethtool_regs_test(struct net_device= *netdev, u64 *data) return !!*data; } +/** + * fbnic_ethtool_msix_test - Verify behavior of NIC interrupts + * @netdev: netdev device to test + * @data: Pointer to results storage + * + * This function is meant to test the global interrupt registers and the + * PCIe IP MSI-X functionality. It essentially goes through and tests + * test various combinations of the set, clear, and mask bits in order to + * verify the behavior is as we expect it to be from the driver. + * + * Return: non-zero on failure. + **/ +static int fbnic_ethtool_msix_test(struct net_device *netdev, u64 *data) +{ + struct fbnic_net *fbn =3D netdev_priv(netdev); + struct fbnic_dev *fbd =3D fbn->fbd; + + *data =3D fbnic_msix_test(fbd); + + return !!*data; +} + static void fbnic_self_test(struct net_device *netdev, struct ethtool_test *eth_test, u64 *data) { @@ -1508,6 +1532,7 @@ static void fbnic_self_test(struct net_device *netdev, if (!(eth_test->flags & ETH_TEST_FL_OFFLINE)) { data[TEST_REG] =3D 0; + data[TEST_MSIX] =3D 0; return; } @@ -1517,6 +1542,9 @@ static void fbnic_self_test(struct net_device *netdev, if (fbnic_ethtool_regs_test(netdev, &data[TEST_REG])) eth_test->flags |=3D ETH_TEST_FL_FAILED; + if (fbnic_ethtool_msix_test(netdev, &data[TEST_MSIX])) + eth_test->flags |=3D ETH_TEST_FL_FAILED; + if (if_running && netif_open(netdev, NULL)) { netdev_err(netdev, "Failed to re-initialize hardware following test\n"); diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_irq.c b/drivers/net/ethe= rnet/meta/fbnic/fbnic_irq.c index 02e8b0b257fe..2099ee89fb51 100644 --- a/drivers/net/ethernet/meta/fbnic/fbnic_irq.c +++ b/drivers/net/ethernet/meta/fbnic/fbnic_irq.c @@ -238,6 +238,160 @@ void fbnic_free_irq(struct fbnic_dev *fbd, int nr, vo= id *data) free_irq(irq, data); } +struct fbnic_msix_test_data { + struct fbnic_dev *fbd; + unsigned long test_msix_status[BITS_TO_LONGS(FBNIC_MAX_MSIX_VECS)]; + int irq_vector[FBNIC_MAX_MSIX_VECS]; +}; + +static irqreturn_t fbnic_irq_test(int irq, void *data) +{ + struct fbnic_msix_test_data *test_data =3D data; + struct fbnic_dev *fbd =3D test_data->fbd; + int i; + + for (i =3D fbd->num_irqs; i--;) { + if (test_data->irq_vector[i] =3D=3D irq) { + set_bit(i, test_data->test_msix_status); + break; + } + } + + return IRQ_HANDLED; +} + +/** + * fbnic_msix_test - Verify behavior of NIC interrupts + * @fbd: device to test + * + * This function is meant to test the global interrupt registers and the + * PCIe IP MSI-X functionality. It essentially goes through and tests + * various combinations of the set, clear, and mask bits in order to + * verify the behavior is as we expect it to be from the driver. + * + * Return: See enum fbnic_msix_self_test_codes + **/ +enum fbnic_msix_self_test_codes fbnic_msix_test(struct fbnic_dev *fbd) +{ + enum fbnic_msix_self_test_codes result =3D FBNIC_TEST_MSIX_SUCCESS; + struct pci_dev *pdev =3D to_pci_dev(fbd->dev); + struct fbnic_msix_test_data *test_data; + u32 mask =3D 0; + int i; + + /* Allocate bitmap and IRQ vector table */ + test_data =3D kzalloc(sizeof(*test_data), GFP_KERNEL); + + /* memory allocation failure */ + if (!test_data) + return FBNIC_TEST_MSIX_NOMEM; + + /* Initialize test data */ + test_data->fbd =3D fbd; + + for (i =3D FBNIC_NON_NAPI_VECTORS; i < fbd->num_irqs; i++) { + /* Add IRQ to vector table so it can be found */ + test_data->irq_vector[i] =3D pci_irq_vector(pdev, i); + + /* Enable the interrupt */ + if (!fbnic_request_irq(fbd, i, fbnic_irq_test, 0, + fbd->netdev->name, test_data)) + continue; + + while (i-- > FBNIC_NON_NAPI_VECTORS) + fbnic_free_irq(fbd, i, test_data); + kfree(test_data); + + /* IRQ request failure */ + return FBNIC_TEST_MSIX_IRQ_REQ_FAIL; + } + + /* Test each bit individually */ + for (i =3D FBNIC_NON_NAPI_VECTORS; i < fbd->num_irqs; i++) { + mask =3D 1U << (i % 32); + + /* Start with mask set and interrupt cleared */ + fbnic_wr32(fbd, FBNIC_INTR_MASK_SET(i / 32), mask); + fbnic_wrfl(fbd); + fbnic_wr32(fbd, FBNIC_INTR_CLEAR(i / 32), mask); + fbnic_wrfl(fbd); + + /* masking failure to prevent interrupt */ + result =3D FBNIC_TEST_MSIX_MASK; + + fbnic_wr32(fbd, FBNIC_INTR_SET(i / 32), mask); + fbnic_wrfl(fbd); + usleep_range(10000, 11000); + + if (test_bit(i, test_data->test_msix_status)) + break; + + /* unmasking failure w/ sw status set */ + result =3D FBNIC_TEST_MSIX_UNMASK; + + fbnic_wr32(fbd, FBNIC_INTR_MASK_CLEAR(i / 32), mask); + fbnic_wrfl(fbd); + usleep_range(10000, 11000); + + if (!test_bit(i, test_data->test_msix_status)) + break; + + /* interrupt when clearing mask */ + result =3D FBNIC_TEST_MSIX_IRQ_CLEAR; + + clear_bit(i, test_data->test_msix_status); + fbnic_wr32(fbd, FBNIC_INTR_MASK_CLEAR(i / 32), mask); + fbnic_wrfl(fbd); + usleep_range(10000, 11000); + + if (test_bit(i, test_data->test_msix_status)) + break; + + /* interrupt not triggering when not masked */ + result =3D FBNIC_TEST_MSIX_NO_INTERRUPT; + + fbnic_wr32(fbd, FBNIC_INTR_SET(i / 32), mask); + fbnic_wrfl(fbd); + usleep_range(10000, 11000); + + if (!test_bit(i, test_data->test_msix_status)) + break; + + /* status not cleared, or mask not set */ + result =3D FBNIC_TEST_MSIX_NO_CLEAR_OR_MASK; + if (mask & fbnic_rd32(fbd, FBNIC_INTR_STATUS(i / 32))) + break; + if (!(mask & fbnic_rd32(fbd, FBNIC_INTR_MASK(i / 32)))) + break; + + /* Result =3D 0 - Success */ + result =3D FBNIC_TEST_MSIX_SUCCESS; + + clear_bit(i, test_data->test_msix_status); + } + + if (i < fbd->num_irqs) { + fbnic_wr32(fbd, FBNIC_INTR_MASK_SET(i / 32), mask); + fbnic_wrfl(fbd); + fbnic_wr32(fbd, FBNIC_INTR_CLEAR(i / 32), mask); + fbnic_wrfl(fbd); + clear_bit(i, test_data->test_msix_status); + } + + for (i =3D FBNIC_NON_NAPI_VECTORS; i < fbd->num_irqs; i++) { + /* Test for bits set after testing */ + if (test_bit(i, test_data->test_msix_status)) + result =3D 70; + + /* Free IRQ */ + fbnic_free_irq(fbd, i, test_data); + } + + kfree(test_data); + + return result; +} + void fbnic_napi_name_irqs(struct fbnic_dev *fbd) { unsigned int i; -- 2.43.0 From nobody Thu Apr 16 08:38:20 2026 Received: from mail-qv1-f46.google.com (mail-qv1-f46.google.com [209.85.219.46]) (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 A408A3019A6 for ; Sun, 1 Mar 2026 11:06:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.219.46 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772363182; cv=none; b=TMGvtxSochXW+uqlWy+POhNnmALv3bXIbvAy1er7PE3XKnlodWCuAU87eDCfK/k0bp2TF1O0IIUajpRqpOrfWi4Eg3BOP8pWW3x2AVXxgKM3h5q0AXNwNTMR0+9cgTUo8EmhwUxnkJMqj9lX/GupO8Yb6/oWh4/MItQ0mZAPwnk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772363182; c=relaxed/simple; bh=TIvE4y4LuRiV70aS2fW22mvfHHc91g0ORgv1VYahyZU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=BKmrBhS6BNeVGXaJK3cqEkLzhXoDYXcqjTJM+QW84OT5nLxaxSexepxpuJOJ6Fcfj1kU6k9z5vsh6qav8U2vapVkQ62E68xK+JV8r9r579PI5NTt8LS6bWbgGwQGde2Wxno+15IE3dsrZzOBwnHaxTn1+tio49MYG/1H1ldldR4= 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=j7IUnT3h; arc=none smtp.client-ip=209.85.219.46 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="j7IUnT3h" Received: by mail-qv1-f46.google.com with SMTP id 6a1803df08f44-897023602b1so47970196d6.0 for ; Sun, 01 Mar 2026 03:06:20 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1772363180; x=1772967980; 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=Rd12nlrpOUc6ulbomkWhJgpuZGNyjxegNqIZtOfR/6E=; b=j7IUnT3hXVBby00l+/HbfABENPZifMURJKxbE83l8U6u/0aBqrbXslaq2EIWvXCNAC wwJD682f5oVurDurmg7BXGuQ9i8tY0aJGB4FX15rgci7qQlSWYWpwTTNWSih9+NIDoBD 9s5/sXhgK9uivmlitpazjBMQS/v5o5UNJ74qdzkRxo6gKdsFMUH+cv378GcKLS/N0d6K njHzH1lMWel2TeEVI1cuhdHmw7BLD9VqnyMOally6mbEukFKawd8DsL4QHulMpVnA/KK loEIaN6gocndzKRWeIkktLB0/hwejmcHVmGqPv8A2x49llo9+Kvgyiw8Xj8pSiSrIMwM ENCQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772363180; x=1772967980; 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=Rd12nlrpOUc6ulbomkWhJgpuZGNyjxegNqIZtOfR/6E=; b=IS2pbMyIBYYUyOIGt5qdMV3/I9YRse5YV4BrkJrkXObq2USWj08JhetyBtPaDA2vR7 kmT1MA8NCL+zHLhczP8NbCdxtiINsdqegBlJdUogjWF+DZpM1qgGPDSBKNMM3Qag7B4a x0My+ZUDD5vGE0JgIWYc0JaXtSiD+r9XapfGpk6tChq6/t2jqFx2eP6HhCpseKmR2Qj0 rBbB6V5YlBhZWANkG0N4Esc9vfT3YhAxJTwTfLaTM0LpVlhqOfKG6LmODAAVqfdxzz2A EV4gGEwe/c9VCv7gm6inDO4w7oFXefXa35nyKfgR3DZx1dM2TaxGo0lxgrzSHMlYHiDi 7aBQ== X-Forwarded-Encrypted: i=1; AJvYcCV11nBWT4ps3wRBSOQOmzc/G9ttVeHbNTUvSbAL/NLzlGvCEQZ7GFkTxGPrxHTnLQyv//GhHtBWz+qJx48=@vger.kernel.org X-Gm-Message-State: AOJu0YyxFWpSmKtY1QNQ7NergCV+nnlRWUgA0RfBiyx0t7WHSlDK3b6i 5Br/BthnqDw/O6IfaDYX6hIT4CIa5MH6272vHX1A7A5czLrNstwoyepa X-Gm-Gg: ATEYQzxTSOzD27lLEqsvq0Txl/A5W4JoaUBWLu+TJMx16KHB3yV3TYJUEWeE0bz2thc GAJhOMxGngdrZrUrH8LExBQHO5oKaGc9uWbrZO1ANfXleoH564/t3qcd9jMiPlgpLlb3wqBSiH6 8XvGygh44wDzgF+Yncpv3iVVfwZTRUmSsTMpDemdxiXnLyt9ZUYVBNJZE2rQMRay0CGFiMGrVsf s9evkqjKaQqBpgqnPRjGYaYOVtkiRy/xkUGFP195LW5vGFpvES+CscALmMj5ApSkmfovLP/KVjq JaYYnIecqvbwJu38wewArLrvVPjOgmpPgpbdVMbyyXL2kQUdTLg1sm7rIGKhalx7wce6nazNYYn pWvA/AQR/8562KI2X5zyMRzijkcZIq2tGrSPGDsM7viSDCqY0ySYFgGXXmthQhDQips0C/nfnV0 BtsXb0tfuuZUOK1nExVxAiwOnCz5k9zTloRHp6aKT5WPtUCWeX7fwz6ZOU9G267lzn9XkZj3jJQ 8ppgcI11moII1RC X-Received: by 2002:a05:6214:d09:b0:899:efd1:9e15 with SMTP id 6a1803df08f44-899efd1a067mr34565596d6.49.1772363179520; Sun, 01 Mar 2026 03:06:19 -0800 (PST) Received: from PF5YBGDS.localdomain (70.15.25.19.res-cmts.sm3.ptd.net. [70.15.25.19]) by smtp.gmail.com with ESMTPSA id 6a1803df08f44-899c716caebsm83888876d6.15.2026.03.01.03.06.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 01 Mar 2026 03:06:19 -0800 (PST) From: mike.marciniszyn@gmail.com To: Alexander Duyck , Jakub Kicinski , kernel-team@meta.com, Andrew Lunn , "David S. Miller" , Eric Dumazet , Paolo Abeni , Simon Horman , Russell King , Jacob Keller , Lee Trager , Mohsin Bashir , Dan Carpenter , Pei Xiao , Stanislav Fomichev , Kuniyuki Iwashima , Samiullah Khawaja , Hangbin Liu Cc: mike.marciniszyn@gmail.com, netdev@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH net-next v2.2 4/5] eth fbnic: TLV support for use by MBX self test Date: Sun, 1 Mar 2026 06:06:05 -0500 Message-ID: <20260301110606.3739-5-mike.marciniszyn@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260301110606.3739-1-mike.marciniszyn@gmail.com> References: <20260301110606.3739-1-mike.marciniszyn@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" From: "Mike Marciniszyn (Meta)" The TLV (Type-Value-Length) self uses a known set of data to create a TLV message. These routines support the MBX self test by creating the test messages and parsing the response message coming back from the firmware. Signed-off-by: Mike Marciniszyn (Meta) --- v2 - place forward of struct fbnic_dev after include with a blank line drivers/net/ethernet/meta/fbnic/fbnic_tlv.c | 276 ++++++++++++++++++++ drivers/net/ethernet/meta/fbnic/fbnic_tlv.h | 27 ++ 2 files changed, 303 insertions(+) diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_tlv.c b/drivers/net/ethe= rnet/meta/fbnic/fbnic_tlv.c index 517ed8b2f1cb..c55d4f76a5fc 100644 --- a/drivers/net/ethernet/meta/fbnic/fbnic_tlv.c +++ b/drivers/net/ethernet/meta/fbnic/fbnic_tlv.c @@ -551,6 +551,172 @@ int fbnic_tlv_parser_error(void *opaque, struct fbnic= _tlv_msg **results) return -EBADMSG; } +#define FBNIC_TLV_TEST_STRING_LEN 32 + +struct fbnic_tlv_test { + u64 test_u64; + s64 test_s64; + u32 test_u32; + s32 test_s32; + u16 test_u16; + s16 test_s16; + u8 test_mac[ETH_ALEN]; + u8 test_mac_array[4][ETH_ALEN]; + u8 test_true; + u8 test_false; + char test_string[FBNIC_TLV_TEST_STRING_LEN]; +}; + +static struct fbnic_tlv_test test_struct; + +const struct fbnic_tlv_index fbnic_tlv_test_index[] =3D { + FBNIC_TLV_ATTR_U64(FBNIC_TLV_TEST_MSG_U64), + FBNIC_TLV_ATTR_S64(FBNIC_TLV_TEST_MSG_S64), + FBNIC_TLV_ATTR_U32(FBNIC_TLV_TEST_MSG_U32), + FBNIC_TLV_ATTR_S32(FBNIC_TLV_TEST_MSG_S32), + FBNIC_TLV_ATTR_U32(FBNIC_TLV_TEST_MSG_U16), + FBNIC_TLV_ATTR_S32(FBNIC_TLV_TEST_MSG_S16), + FBNIC_TLV_ATTR_MAC_ADDR(FBNIC_TLV_TEST_MSG_MAC_ADDR), + FBNIC_TLV_ATTR_FLAG(FBNIC_TLV_TEST_MSG_FLAG_TRUE), + FBNIC_TLV_ATTR_FLAG(FBNIC_TLV_TEST_MSG_FLAG_FALSE), + FBNIC_TLV_ATTR_STRING(FBNIC_TLV_TEST_MSG_STRING, + FBNIC_TLV_TEST_STRING_LEN), + FBNIC_TLV_ATTR_ARRAY(FBNIC_TLV_TEST_MSG_ARRAY), + FBNIC_TLV_ATTR_NESTED(FBNIC_TLV_TEST_MSG_NESTED), + FBNIC_TLV_ATTR_LAST +}; + +static void fbnic_tlv_test_struct_init(void) +{ + int i =3D FBNIC_TLV_TEST_STRING_LEN - 1; + + /* Populate the struct with random data */ + get_random_once(&test_struct, + offsetof(struct fbnic_tlv_test, test_string) + i); + + /* Force true/false to their expected values */ + test_struct.test_false =3D false; + test_struct.test_true =3D true; + + /* Convert test_string to a true ASCII string */ + test_struct.test_string[i] =3D '\0'; + while (i--) { + /* Force characters into displayable range */ + if (test_struct.test_string[i] < 64 || + test_struct.test_string[i] >=3D 96) { + test_struct.test_string[i] %=3D 32; + test_struct.test_string[i] +=3D 64; + } + } +} + +static int fbnic_tlv_test_attr_data(struct fbnic_tlv_msg *msg) +{ + struct fbnic_tlv_msg *array; + int err, i; + + err =3D fbnic_tlv_attr_put_int(msg, FBNIC_TLV_TEST_MSG_U64, + test_struct.test_u64); + if (err) + return err; + + err =3D fbnic_tlv_attr_put_int(msg, FBNIC_TLV_TEST_MSG_S64, + test_struct.test_s64); + if (err) + return err; + + err =3D fbnic_tlv_attr_put_int(msg, FBNIC_TLV_TEST_MSG_U32, + test_struct.test_u32); + if (err) + return err; + + err =3D fbnic_tlv_attr_put_int(msg, FBNIC_TLV_TEST_MSG_S32, + test_struct.test_s32); + if (err) + return err; + + err =3D fbnic_tlv_attr_put_int(msg, FBNIC_TLV_TEST_MSG_U16, + test_struct.test_u16); + if (err) + return err; + + err =3D fbnic_tlv_attr_put_int(msg, FBNIC_TLV_TEST_MSG_S16, + test_struct.test_s16); + if (err) + return err; + + err =3D fbnic_tlv_attr_put_value(msg, FBNIC_TLV_TEST_MSG_MAC_ADDR, + test_struct.test_mac, ETH_ALEN); + if (err) + return err; + + /* Start MAC address array */ + array =3D fbnic_tlv_attr_nest_start(msg, FBNIC_TLV_TEST_MSG_ARRAY); + if (!array) + return -ENOSPC; + + for (i =3D 0; i < 4; i++) { + err =3D fbnic_tlv_attr_put_value(array, + FBNIC_TLV_TEST_MSG_MAC_ADDR, + test_struct.test_mac_array[i], + ETH_ALEN); + if (err) + return err; + } + + /* Close array */ + fbnic_tlv_attr_nest_stop(msg); + + err =3D fbnic_tlv_attr_put_flag(msg, FBNIC_TLV_TEST_MSG_FLAG_TRUE); + if (err) + return err; + + return fbnic_tlv_attr_put_string(msg, FBNIC_TLV_TEST_MSG_STRING, + test_struct.test_string); +} + +/** + * fbnic_tlv_test_create - Allocate a test message and fill it w/ data + * @fbd: FBNIC device structure + * + * Return: NULL on failure to allocate or pointer to new TLV test message. + **/ +struct fbnic_tlv_msg *fbnic_tlv_test_create(struct fbnic_dev *fbd) +{ + struct fbnic_tlv_msg *msg, *nest; + int err; + + msg =3D fbnic_tlv_msg_alloc(FBNIC_TLV_MSG_ID_TEST); + if (!msg) + return NULL; + + /* Randomize struct data */ + fbnic_tlv_test_struct_init(); + + /* Add first level of data to message */ + err =3D fbnic_tlv_test_attr_data(msg); + if (err) + goto free_message; + + /* Start second level nested */ + nest =3D fbnic_tlv_attr_nest_start(msg, FBNIC_TLV_TEST_MSG_NESTED); + if (!nest) + goto free_message; + + /* Add nested data */ + err =3D fbnic_tlv_test_attr_data(nest); + if (err) + goto free_message; + + /* Close nest and report full message */ + fbnic_tlv_attr_nest_stop(msg); + + return msg; +free_message: + free_page((unsigned long)msg); + return NULL; +} + void fbnic_tlv_attr_addr_copy(u8 *dest, struct fbnic_tlv_msg *src) { u8 *mac_addr; @@ -558,3 +724,113 @@ void fbnic_tlv_attr_addr_copy(u8 *dest, struct fbnic_= tlv_msg *src) mac_addr =3D fbnic_tlv_attr_get_value_ptr(src); memcpy(dest, mac_addr, ETH_ALEN); } + +/** + * fbnic_tlv_parser_test_attr - Function loading test attributes into stru= cture + * @str: Test structure to load + * @results: Pointer to results array + * + * Copies attributes into structure. Any attribute that doesn't exist in t= he + * results array is not populated. + **/ +static void fbnic_tlv_parser_test_attr(struct fbnic_tlv_test *str, + struct fbnic_tlv_msg **results) +{ + struct fbnic_tlv_msg *array_results[4]; + struct fbnic_tlv_msg *attr; + char *string =3D NULL; + int i, err; + + str->test_u64 =3D fta_get_uint(results, FBNIC_TLV_TEST_MSG_U64); + str->test_u32 =3D fta_get_uint(results, FBNIC_TLV_TEST_MSG_U32); + str->test_u16 =3D fta_get_uint(results, FBNIC_TLV_TEST_MSG_U16); + + str->test_s64 =3D fta_get_sint(results, FBNIC_TLV_TEST_MSG_S64); + str->test_s32 =3D fta_get_sint(results, FBNIC_TLV_TEST_MSG_S32); + str->test_s16 =3D fta_get_sint(results, FBNIC_TLV_TEST_MSG_S16); + + attr =3D results[FBNIC_TLV_TEST_MSG_MAC_ADDR]; + if (attr) + fbnic_tlv_attr_addr_copy(str->test_mac, attr); + + attr =3D results[FBNIC_TLV_TEST_MSG_ARRAY]; + if (attr) { + int len =3D le16_to_cpu(attr->hdr.len) / sizeof(u32) - 1; + + err =3D fbnic_tlv_attr_parse_array(&attr[1], len, + array_results, + fbnic_tlv_test_index, + FBNIC_TLV_TEST_MSG_MAC_ADDR, + 4); + if (!err) { + for (i =3D 0; i < 4 && array_results[i]; i++) + fbnic_tlv_attr_addr_copy(str->test_mac_array[i], + array_results[i]); + } + } + + str->test_true =3D !!results[FBNIC_TLV_TEST_MSG_FLAG_TRUE]; + str->test_false =3D !!results[FBNIC_TLV_TEST_MSG_FLAG_FALSE]; + + attr =3D results[FBNIC_TLV_TEST_MSG_STRING]; + if (attr) { + string =3D fbnic_tlv_attr_get_value_ptr(attr); + strscpy(str->test_string, string, FBNIC_TLV_TEST_STRING_LEN); + } +} + +static void fbnic_tlv_test_dump(struct fbnic_tlv_test *value, char *prefix) +{ + print_hex_dump(KERN_INFO, prefix, DUMP_PREFIX_OFFSET, 16, 1, + value, sizeof(*value), true); +} + +/** + * fbnic_tlv_parser_test - Function for parsing and testing test message + * @opaque: Unused value + * @results: Results of parser output + * + * Return: negative value on error, or 0 on success. + * + * Parses attributes to structures and compares the structure to the + * expected test value that should have been used to populate the message. + * + * Used to verify message generation and parser are working correctly. + **/ +int fbnic_tlv_parser_test(void *opaque, struct fbnic_tlv_msg **results) +{ + struct fbnic_tlv_msg *nest_results[FBNIC_TLV_RESULTS_MAX] =3D { 0 }; + struct fbnic_tlv_test result_struct; + struct fbnic_tlv_msg *attr; + int err; + + memset(&result_struct, 0, sizeof(result_struct)); + fbnic_tlv_parser_test_attr(&result_struct, results); + + if (memcmp(&test_struct, &result_struct, sizeof(test_struct))) { + fbnic_tlv_test_dump(&result_struct, "fbnic: found - "); + fbnic_tlv_test_dump(&test_struct, "fbnic: expected - "); + return -EINVAL; + } + + attr =3D results[FBNIC_TLV_TEST_MSG_NESTED]; + if (!attr) + return -EINVAL; + + err =3D fbnic_tlv_attr_parse(&attr[1], + le16_to_cpu(attr->hdr.len) / sizeof(u32) - 1, + nest_results, fbnic_tlv_test_index); + if (err) + return err; + + memset(&result_struct, 0, sizeof(result_struct)); + fbnic_tlv_parser_test_attr(&result_struct, nest_results); + + if (memcmp(&test_struct, &result_struct, sizeof(test_struct))) { + fbnic_tlv_test_dump(&result_struct, "fbnic: found - "); + fbnic_tlv_test_dump(&test_struct, "fbnic: expected - "); + return -EINVAL; + } + + return 0; +} diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_tlv.h b/drivers/net/ethe= rnet/meta/fbnic/fbnic_tlv.h index 3508b46ebdd0..9c4e4759394a 100644 --- a/drivers/net/ethernet/meta/fbnic/fbnic_tlv.h +++ b/drivers/net/ethernet/meta/fbnic/fbnic_tlv.h @@ -9,6 +9,8 @@ #include #include +struct fbnic_dev; + #define FBNIC_TLV_MSG_ALIGN(len) ALIGN(len, sizeof(u32)) #define FBNIC_TLV_MSG_SIZE(len) \ (FBNIC_TLV_MSG_ALIGN(len) / sizeof(u32)) @@ -153,6 +155,31 @@ int fbnic_tlv_parser_error(void *opaque, struct fbnic_= tlv_msg **results); #define fta_get_str(_results, _id, _dst, _dstsize) \ fbnic_tlv_attr_get_string(_results[_id], _dst, _dstsize) +#define FBNIC_TLV_MSG_ID_TEST 0 + +enum fbnic_tlv_test_attr_id { + FBNIC_TLV_TEST_MSG_U64, + FBNIC_TLV_TEST_MSG_S64, + FBNIC_TLV_TEST_MSG_U32, + FBNIC_TLV_TEST_MSG_S32, + FBNIC_TLV_TEST_MSG_U16, + FBNIC_TLV_TEST_MSG_S16, + FBNIC_TLV_TEST_MSG_MAC_ADDR, + FBNIC_TLV_TEST_MSG_FLAG_TRUE, + FBNIC_TLV_TEST_MSG_FLAG_FALSE, + FBNIC_TLV_TEST_MSG_STRING, + FBNIC_TLV_TEST_MSG_NESTED, + FBNIC_TLV_TEST_MSG_ARRAY, + FBNIC_TLV_TEST_MSG_MAX +}; + +extern const struct fbnic_tlv_index fbnic_tlv_test_index[]; +struct fbnic_tlv_msg *fbnic_tlv_test_create(struct fbnic_dev *fbd); +int fbnic_tlv_parser_test(void *opaque, struct fbnic_tlv_msg **results); + +#define FBNIC_TLV_MSG_TEST \ + FBNIC_TLV_PARSER(TEST, fbnic_tlv_test_index, \ + fbnic_tlv_parser_test) #define FBNIC_TLV_MSG_ERROR \ FBNIC_TLV_PARSER(UNKNOWN, NULL, fbnic_tlv_parser_error) #endif /* _FBNIC_TLV_H_ */ -- 2.43.0 From nobody Thu Apr 16 08:38:20 2026 Received: from mail-qt1-f177.google.com (mail-qt1-f177.google.com [209.85.160.177]) (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 89E633002DC for ; Sun, 1 Mar 2026 11:06:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.160.177 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772363187; cv=none; b=Ncy+wIKx3CT3XyU1nDXWScz8BWXJr8K1e6vplm/u3ETKeIf2+j7J1KytL2CQTwIlpXOe/ixQ4srZF6t0w1ZauCD/PbNeP58i0mqTGs5K9Fl6aZqAVJ7bxCqgDEch2+zOe1vCOhlvVhVzjsbpNBW4W9/MOHF5YlWSJsOGK+dEIZs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772363187; c=relaxed/simple; bh=QMJrFlWUxw3eCzl7CbbaUnvVP2sFPLmXBpj62mRAmvw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=uH2aVEa/KSOiuD4i4v1NyDp+/HLNvq31OnVij4vtBd4XmGuGbJSRDotHLZG6EfkuMzgWGkMloRVupJAtZb/AQ1y7F53HpkTXO7NP0KfiCMITmvNl2FEcxr9IZq0/MuhWo99vjS8ZOroV2NOOs/QFdPx3KWtEk8FHwKEJvh3cluY= 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=EGasVczi; arc=none smtp.client-ip=209.85.160.177 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="EGasVczi" Received: by mail-qt1-f177.google.com with SMTP id d75a77b69052e-506a019a7f3so45941431cf.3 for ; Sun, 01 Mar 2026 03:06:22 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1772363181; x=1772967981; 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=e+nYx3bJb71EY0N2U95E2xjSNTPJeUPvPHdUZAbp4Fk=; b=EGasVczincz8GCnYOK3VoRztMeQp2VTAGsJnt01ypwKa2E3tUxGBmu/DyW8s49u/u1 ktbRZHxj8MjYj3rR/HlgRkWHCz7w4xh+smcYPnEUDebH+5JkosaN2Ri4LfnvbK3PNovD ZwmJH/OXWfRCiJz8OPF6S+nW8bAZentWoYlx80MFGOiKK0GZWP1eBwzPQK5wdEMZoDBG e6PhxGHBnbCVjJiCxToClEvwcEONGZYb7WdohcU2313AQ8pKSzfWsuDMzCi2JwjjKIT3 6jhR4zVD8KnhPk9uyt0aSBVmxdIBWdzUxuw/tDZwhID/OJU/VgyyEDt2xTJgwhtfNSL7 /sxA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772363181; x=1772967981; 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=e+nYx3bJb71EY0N2U95E2xjSNTPJeUPvPHdUZAbp4Fk=; b=hC00E8on1jXXTXN5YOMU3hvpnKwLtaxYcXwdN93xiZ8WoxUnnX9vUEOPn2ySBBqBYD 72l17I8ApK1LRE48Rglvt5Wcj0SaXgq4q1Jmv1+2T96EslDQDn1bd8tIvtWO4WHQV3Ai FcbMgR1/wcFQXeGRkspoaFbfiUcS+IXgNdHm6HgU4T4gbYolBY+vSRKGwCBFZ8r7ajzn 5I0bzwFPEuZfPkZKWeI2GZCVCZcnoZxV1Ttojai0LKmbUZX1BtV8k/7PLJDpqoDoK6cP 0OxwGcizZzZY6CQMAdGQwmEW2k+iHRaa59lPW6/mXXiAq+83EKO2ZrTLKTY+2B2tio9F 9zyg== X-Forwarded-Encrypted: i=1; AJvYcCX/8LTUzqYdYHxjDgycAwUeY5w3qy4IcS9gRHGOapbBnhocwbXI+Cz4qcSFAnE1jL+w8k0OSeVhpRFMZyQ=@vger.kernel.org X-Gm-Message-State: AOJu0Yw6aLnX8uLdwJ9JrwaQ1uvaT2LqLcdSJQqW6a6kaY2IFTFEtloc pX/2uQPvFsoJnWBMhIpRAimX9mxXbiSaf9GMGptXrQ8HUsEKcd1N503I X-Gm-Gg: ATEYQzwCFGwhOMo3CuzItYZxohNNNJIiUGKPzHvedeIHlvVD/PbP5DTp/A/5lmIzwzl zH2ihpffvu1AoWQF0rwU8jEZQb+NSHfpueD0s3qMiXAqQz/D/ST/9kvo1+AcCU41qAPctmi3zXr 9yR0pv8esbK7UcJ7yFMY8siafLlxEvWhngRhaxPs1zZfnOU6301GgbewFXudYadECI/mOvwXySv +g1ZaroJIbVfXRtT4AYl2p1NlEAfOMGFZ0KTLyaLBhWvRZVDI4RyNkezJ1SSAGLg9aeHYDwmqFP fS6Gxd5WPh6NZcsEGMJJrDuXDAj7Yyrr/8FZeZRP6CjgNlJVbTXQGn6G+zoxBzyi1afDKkAI624 drB0/7bvwRrcMxSM6UG7S6vu1SEJnni/JyxUyIXLYhF5bjBX0bz8UsXIrKY33V5yb1eu3HqOukT s0InnJF0LlpIVPQJGG5YI5y6DK5a4jrTWy3uwJ8gVJ3lZHBis1RDRLvYmfsqZNpL8GGFBoniDhQ iKWa749gv9wRHgr X-Received: by 2002:ac8:57d2:0:b0:4ee:2352:1bb1 with SMTP id d75a77b69052e-5075273a9ebmr123554541cf.5.1772363181422; Sun, 01 Mar 2026 03:06:21 -0800 (PST) Received: from PF5YBGDS.localdomain (70.15.25.19.res-cmts.sm3.ptd.net. [70.15.25.19]) by smtp.gmail.com with ESMTPSA id 6a1803df08f44-899c716caebsm83888876d6.15.2026.03.01.03.06.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 01 Mar 2026 03:06:21 -0800 (PST) From: mike.marciniszyn@gmail.com To: Alexander Duyck , Jakub Kicinski , kernel-team@meta.com, Andrew Lunn , "David S. Miller" , Eric Dumazet , Paolo Abeni , Simon Horman , Russell King , Jacob Keller , Lee Trager , Mohsin Bashir , Dan Carpenter , Pei Xiao , Stanislav Fomichev , Kuniyuki Iwashima , Samiullah Khawaja , Hangbin Liu Cc: mike.marciniszyn@gmail.com, netdev@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH net-next v2.2 5/5] eth fbnic: Add mailbox self test Date: Sun, 1 Mar 2026 06:06:06 -0500 Message-ID: <20260301110606.3739-6-mike.marciniszyn@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260301110606.3739-1-mike.marciniszyn@gmail.com> References: <20260301110606.3739-1-mike.marciniszyn@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" From: "Mike Marciniszyn (Meta)" The mailbox self test ensures the interface to and from the firmware is healthy by sending a test message and fielding the response from the firmware. This patch uses the new completion API [1][2] that allocates a completion structure, binds the completion to the TEST message, and uses a new FW parsing routine that wraps the completion processing around the TLV parser. Link: https://patch.msgid.link/20250516164804.741348-1-lee@trager.us [1] Link: https://patch.msgid.link/20260115003353.4150771-6-mohsin.bashr@gmail.= com [2] Signed-off-by: Mike Marciniszyn (Meta) --- v2 - add enum for test return codes drivers/net/ethernet/meta/fbnic/fbnic.h | 14 ++- .../net/ethernet/meta/fbnic/fbnic_ethtool.c | 15 +++ drivers/net/ethernet/meta/fbnic/fbnic_fw.c | 100 ++++++++++++++++++ drivers/net/ethernet/meta/fbnic/fbnic_fw.h | 27 +++++ 3 files changed, 142 insertions(+) diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c b/drivers/net/= ethernet/meta/fbnic/fbnic_ethtool.c index b0c8d1b069e2..251de64baa5a 100644 --- a/drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c +++ b/drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c @@ -129,11 +129,13 @@ static const struct fbnic_stat fbnic_gstrings_xdp_sta= ts[] =3D { enum fbnic_self_test_results { TEST_REG =3D 0, TEST_MSIX, + TEST_MBX, }; static const char fbnic_gstrings_self_test[][ETH_GSTRING_LEN] =3D { [TEST_REG] =3D "Register test (offline)", [TEST_MSIX] =3D "MSI-X Interrupt test (offline)", + [TEST_MBX] =3D "FW mailbox test (on/offline)", }; #define FBNIC_TEST_LEN ARRAY_SIZE(fbnic_gstrings_self_test) @@ -1525,11 +1527,24 @@ static int fbnic_ethtool_msix_test(struct net_devic= e *netdev, u64 *data) return !!*data; } +static int fbnic_ethtool_mbx_self_test(struct net_device *netdev, u64 *dat= a) +{ + struct fbnic_net *fbn =3D netdev_priv(netdev); + struct fbnic_dev *fbd =3D fbn->fbd; + + *data =3D fbnic_fw_mbx_self_test(fbd); + + return !!*data; +} + static void fbnic_self_test(struct net_device *netdev, struct ethtool_test *eth_test, u64 *data) { bool if_running =3D netif_running(netdev); + if (fbnic_ethtool_mbx_self_test(netdev, &data[TEST_MBX])) + eth_test->flags |=3D ETH_TEST_FL_FAILED; + if (!(eth_test->flags & ETH_TEST_FL_OFFLINE)) { data[TEST_REG] =3D 0; data[TEST_MSIX] =3D 0; diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_fw.c b/drivers/net/ether= net/meta/fbnic/fbnic_fw.c index 1f0b6350bef4..c2bad51bdde6 100644 --- a/drivers/net/ethernet/meta/fbnic/fbnic_fw.c +++ b/drivers/net/ethernet/meta/fbnic/fbnic_fw.c @@ -378,6 +378,37 @@ fbnic_fw_get_cmpl_by_type(struct fbnic_dev *fbd, u32 m= sg_type) return cmpl_data; } +/** + * fbnic_fw_xmit_test_msg - Create and transmit a test message to FW mailb= ox + * @fbd: FBNIC device structure + * @cmpl: fw completion struct + * + * Return: zero on success, negative value on failure + * + * Generates a single page mailbox test message and places it in the Tx + * mailbox queue. Expectation is that the FW will validate that the nested + * value matches the external values, and then will echo them back to us. + * + * Also sets a completion slot for use in the completion wait calls when + * the cmpl arg is non-NULL. + */ +int fbnic_fw_xmit_test_msg(struct fbnic_dev *fbd, + struct fbnic_fw_completion *cmpl) +{ + struct fbnic_tlv_msg *test_msg; + int err; + + test_msg =3D fbnic_tlv_test_create(fbd); + if (!test_msg) + return -ENOMEM; + + err =3D fbnic_mbx_map_req_w_cmpl(fbd, test_msg, cmpl); + if (err) + free_page((unsigned long)test_msg); + + return err; +} + /** * fbnic_fw_xmit_simple_msg - Transmit a simple single TLV message w/o data * @fbd: FBNIC device structure @@ -1556,7 +1587,29 @@ int fbnic_fw_xmit_send_logs(struct fbnic_dev *fbd, b= ool enable, return err; } +static int +fbnic_fw_parser_test(void *opaque, struct fbnic_tlv_msg **results) +{ + struct fbnic_fw_completion *cmpl; + struct fbnic_dev *fbd =3D opaque; + int err; + + /* find cmpl */ + cmpl =3D fbnic_fw_get_cmpl_by_type(fbd, FBNIC_TLV_MSG_ID_TEST); + if (!cmpl) + return -ENOSPC; + + err =3D fbnic_tlv_parser_test(opaque, results); + + cmpl->result =3D err; + complete(&cmpl->done); + fbnic_fw_put_cmpl(cmpl); + + return err; +} + static const struct fbnic_tlv_parser fbnic_fw_tlv_parser[] =3D { + FBNIC_TLV_PARSER(TEST, fbnic_tlv_test_index, fbnic_fw_parser_test), FBNIC_TLV_PARSER(FW_CAP_RESP, fbnic_fw_cap_resp_index, fbnic_fw_parse_cap_resp), FBNIC_TLV_PARSER(OWNERSHIP_RESP, fbnic_ownership_resp_index, @@ -1787,6 +1840,53 @@ void fbnic_mbx_flush_tx(struct fbnic_dev *fbd) } while (time_is_after_jiffies(timeout)); } +/** + * fbnic_fw_mbx_self_test() - verify firmware interface + * @fbd: device to test + * + * This function tests the interfaces to/from the firmware. + * + * Return: See enum fbnic_fw_self_test_codes + **/ +enum fbnic_fw_self_test_codes fbnic_fw_mbx_self_test(struct fbnic_dev *fbd) +{ + enum fbnic_fw_self_test_codes err; + struct fbnic_fw_completion *cmpl; + + /* Skip test if FW interface is not present */ + if (!fbnic_fw_present(fbd)) + return FBNIC_TEST_FW_NO_FIRMWARE; + + cmpl =3D fbnic_fw_alloc_cmpl(FBNIC_TLV_MSG_ID_TEST); + if (!cmpl) + return FBNIC_TEST_FW_NO_CMPL; + + /* Load a test message onto the FW mailbox interface + * and arm the completion. + */ + err =3D fbnic_fw_xmit_test_msg(fbd, cmpl); + if (err) { + err =3D FBNIC_TEST_FW_NO_XMIT; + goto exit_free; + } + + /* Verify we received a message back */ + if (!fbnic_mbx_wait_for_cmpl(cmpl)) { + err =3D FBNIC_TEST_FW_NO_MSG; + goto exit_cleanup; + } + + /* Verify there were no parsing errors */ + if (cmpl->result) + err =3D FBNIC_TEST_FW_PARSE; +exit_cleanup: + fbnic_mbx_clear_cmpl(fbd, cmpl); +exit_free: + fbnic_fw_put_cmpl(cmpl); + + return err; +} + int fbnic_fw_xmit_rpc_macda_sync(struct fbnic_dev *fbd) { struct fbnic_tlv_msg *mac_array; diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_fw.h b/drivers/net/ether= net/meta/fbnic/fbnic_fw.h index 8f7218900562..d84723e4cfa3 100644 --- a/drivers/net/ethernet/meta/fbnic/fbnic_fw.h +++ b/drivers/net/ethernet/meta/fbnic/fbnic_fw.h @@ -104,6 +104,33 @@ void fbnic_mbx_clear_cmpl(struct fbnic_dev *fbd, void fbnic_mbx_poll(struct fbnic_dev *fbd); int fbnic_mbx_poll_tx_ready(struct fbnic_dev *fbd); void fbnic_mbx_flush_tx(struct fbnic_dev *fbd); + +/** + * enum fbnic_fw_self_test_codes - return codes from self test routines + * + * These are the codes returned from the self test routines and + * stored in the test result array indexed by the specific + * test name. + * + * @FBNIC_TEST_FW_SUCCESS: test success + * @FBNIC_TEST_FW_NO_FIRMWARE: FW interface not present + * @FBNIC_TEST_FW_NO_CMPL: No completion available + * @FBNIC_TEST_FW_NO_XMIT: Could not xmit message + * @FBNIC_TEST_FW_NO_MSG: no message returned + * @FBNIC_TEST_FW_PARSE: returned message had parsing error + */ +enum fbnic_fw_self_test_codes { + FBNIC_TEST_FW_SUCCESS =3D 0, + FBNIC_TEST_FW_NO_FIRMWARE =3D 10, + FBNIC_TEST_FW_NO_CMPL =3D 20, + FBNIC_TEST_FW_NO_XMIT =3D 30, + FBNIC_TEST_FW_NO_MSG =3D 40, + FBNIC_TEST_FW_PARSE =3D 50, +}; + +enum fbnic_fw_self_test_codes fbnic_fw_mbx_self_test(struct fbnic_dev *fbd= ); +int fbnic_fw_xmit_test_msg(struct fbnic_dev *fbd, + struct fbnic_fw_completion *c); int fbnic_fw_xmit_ownership_msg(struct fbnic_dev *fbd, bool take_ownership= ); int fbnic_fw_init_heartbeat(struct fbnic_dev *fbd, bool poll); void fbnic_fw_check_heartbeat(struct fbnic_dev *fbd); -- 2.43.0