From nobody Thu Apr 9 21:57:29 2026 Received: from mail-qv1-f53.google.com (mail-qv1-f53.google.com [209.85.219.53]) (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 DE4E83BE140 for ; Thu, 5 Mar 2026 15:09:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.219.53 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772723400; cv=none; b=ETsVHEJAk+GTLen66/8rCU8m//RvLLA76iblbg7GqgMLF3G2TcYIENEnLb4IArNxUto2gscvYOxltX2P4OUSyCwJZAnYqBBYftgJsvEVC0NxkQikkjU9dQukt0ZQn02L8taGQ+IssdTK1cuzAhrjFa+a+PkHFyTUoGenQNZc+R4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772723400; c=relaxed/simple; bh=5JIVRcYl1y12S5/sz2fI5bGqsHsFXiIj4xW4ZbCUe/c=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=QXscPPsbYd1QS9fXQn8TPDpvO6XbJDoHHSJFxVoZxy4OJxW2ZCFKHkrhlabekp8O5dmzrGkJXn/Sq33/7y0r3uOtz7EJPX8oieR1+owcI1/Wc/1WqGDQlxNgYWqqLnw/0ugyIq0sH+S19SmPQUptUHXSZeQ8IBDGpTybA2Q8joA= 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=ZgLoptcz; arc=none smtp.client-ip=209.85.219.53 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="ZgLoptcz" Received: by mail-qv1-f53.google.com with SMTP id 6a1803df08f44-89a0ecbc713so36843646d6.1 for ; Thu, 05 Mar 2026 07:09:58 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1772723398; x=1773328198; 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=bjZWJhe0+52/LCoiWbs/Dsrs71ktVY7uZ4rO2FBsX4k=; b=ZgLoptcz/43S5tArg158/8cTvqRCPZ8UcsGIOTUHzfXwRQUw+v7lb1FH8otjexAti4 4/jMbuod+g+eHnaN1+runomgpj/DDYuJxjsxDNDZOnAqQGjsylauZkmaC5NX47FpVTOS jsqfx/PozQzg14wJTMncHjn/QDhZTW3u3xOABgFTMOG0Q1ooVxmbaBFkP12a7mypqbAN UX1RFKMnUCPsfscpomiXvjkJ7Kx013HYhNREl/1fNzXqqd62YndDm7F1llfqRt1gBG30 jdjJn0XrUat9ngQrCaongB8dNVNQsrDU3i86i5GbbGN1757TtOda0cUiJErn+3lMXXm5 mKyw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772723398; x=1773328198; 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=bjZWJhe0+52/LCoiWbs/Dsrs71ktVY7uZ4rO2FBsX4k=; b=KQLx2PYFPRmRBLsP+/esh+hZYtD33TsmWG6BThFWI5iQtPplaM5YW0LLV58uWwg7sH 0e1Q2jgwLIh0cSuF7CG9OlQ5/S8sbPiuGf6SdElVzQfkcwxl7/6PaAeAPMTJ+AfNB5BV aCxvPnnEjwSZb9AquvHqc++kFEyq2NsnTiemtEPjRHsF6FX4BqTqjtNU3wq3GyxMF7Ed jjbsq5wpGitpTLOGmKNaIlgHIOh7+oL2ALIn47Svt0agSFhLwR3Hs1zFHZrGObWQVskx 2TccIZI4qezmbJoJDR/Ns7OauqJaFtyIGF/DYhHKK9uV2a6X/fsOobcW98+v9jjltIbj dqDw== X-Forwarded-Encrypted: i=1; AJvYcCXYvuiPyS6dt01k85mPqduaoDuWQAG1zY0BPSStNUjXtP4KSURUVs45OuQvUWrd1IUX33wFarb4JDZ4+nU=@vger.kernel.org X-Gm-Message-State: AOJu0Yx2l+xCTQtU4pGbb5mQ3BetPPidOotXjRsBtRj+50KY+47D1RIb /OMWAWxkotbsaCcCWnRhx2EkjHXhs3J9JKFCQdw8gOYRUJkHAoZeBA8D X-Gm-Gg: ATEYQzzj8gGRiWEGAVEzmT5/yZjZ8Jz5yCs1KrTaaQsn8IWaK+Q/8ua5eyy6K64+AEL vjF5xx+MTzZZogRV429Qa8+OAqCO2gIyMtkt2Vr/oWnxtNvJP5/ISlDPMZSzYD9M+nU1nf/7BB4 RG2wQ0IEJwwv8iSiLz3f+whagF+1uE8g2RnyWdGuwDDN/khgTiI87RN8++bbvdXJg/Rr2YCZxOh mwAgavpD0Zx+8YR+No5aTjPbeDFHZaYNWWlEk1zvlvY7nMF2MBHvIdVCLE6g+qmG1ytfQW4Us7q 5a9h0KyPm/SeNMiPLrkg+DHKVGkjZbAepIimckDMiZcPWTsr7AYenau1R8G/0ttuNBNMwX26LiX FKNfHgDplzOWE2pwoxKRI/RbKep41ioLnlm1UpD0dotp6cSzUDaTlg4zGWHcaz5HkAssnumYXG0 9pF6jryQBXFLbYYhBM0Azo91W35f5wi9RL/E57AEZPveprULjscrrIkXeeaQVZ6/rzaFOR4GYw+ PSLRaShuTk8VC0I X-Received: by 2002:a05:6214:300d:b0:894:7716:48dd with SMTP id 6a1803df08f44-89a2490a28fmr33947626d6.29.1772723397679; Thu, 05 Mar 2026 07:09:57 -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-89a0bb6e27asm64183176d6.2.2026.03.05.07.09.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 05 Mar 2026 07:09:57 -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 , Willem de Bruijn , Samiullah Khawaja , Hangbin Liu Cc: mike.marciniszyn@gmail.com, netdev@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH net-next v3 1/5] net: export netif_open for self_test usage Date: Thu, 5 Mar 2026 10:09:43 -0500 Message-ID: <20260305150947.16893-2-mike.marciniszyn@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260305150947.16893-1-mike.marciniszyn@gmail.com> References: <20260305150947.16893-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 v3 - 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) =20 return ret; } +EXPORT_SYMBOL(netif_open); =20 static void __dev_close_many(struct list_head *head) { --=20 2.43.0 From nobody Thu Apr 9 21:57:29 2026 Received: from mail-qv1-f41.google.com (mail-qv1-f41.google.com [209.85.219.41]) (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 5887F19E7F7 for ; Thu, 5 Mar 2026 15:10:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.219.41 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772723402; cv=none; b=uxG0G/goXcojkp94X1C1GAqlSm7wC16HL+GslkhxO9+0WL4VbX/diST0qi4X0gFrwyGhR1psJVEaL60bACk3cTbtJJF+FXnm703ipAeSKhM/Y1wWOxO480BsC+WDtKPuVhpKM0lMAIPXKC7H+MMbVDhxcQO6uvTsPJ+fS1Ayw4s= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772723402; c=relaxed/simple; bh=1NS1S6/8Ze2Z0/M3844fFfkCENDcmedAZ/SnBm1J5h0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=RFDlFS9gkGkgGS57HMnbhFobcymjdsWJkcKpvBL+7kiqqwS0SdtnLoq2X0yKN8tAjQNblqbLJBUX6oGyDGxFqVbKgxC4R9dRwlINjDZt3dnSFYCvNwxfE8qgFPFk9Pt6AesaNW9r3UZJn91/29vOwRC8efWRKxgZ3VGPUVZh2+U= 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=DZJRqTVq; arc=none smtp.client-ip=209.85.219.41 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="DZJRqTVq" Received: by mail-qv1-f41.google.com with SMTP id 6a1803df08f44-899f8c33c11so42800396d6.1 for ; Thu, 05 Mar 2026 07:10:00 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1772723399; x=1773328199; 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=75guPzLnund8QIHTGwjGBLHPWaMv1GdwyGtIfQpeONU=; b=DZJRqTVqGm8XIMBBIrM19obpO+LrdXb6lfO4yyl33KFXH+Z67HcLti+fo8FUc9SkGR Bfo+EnQthsGd8ZuYx84ghbMcy196lCzayEQ7nQjJ5NIHQIJz70E+xlg9bVzinXvihADB bZnK+xR1hC6v6pZ5bW4Y73Iz5Hfpob9cuBEH3R6LsZUcnFi0/xyqnxLYi5900AvDyqA2 YKJUbgSJZvywRN9/JLTjrElVjMsdMTz8loYTC56oynFwPc0iK7F0g8dBN15EHFffIU57 MfPfNU0stwJpxKhDP+j6o3QpyawRw9KpqV/7nojoXi+2mBA0p+U8tqIp/3KvTtRap5/I uREg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772723399; x=1773328199; 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=75guPzLnund8QIHTGwjGBLHPWaMv1GdwyGtIfQpeONU=; b=h+1t/i5Ej7bvCm8NNqK9dCTd0+tMkauowG1ZQzYh1DUakRoxZPzIJvKY6+G78ZV92k 1EXM+QrtgEGJLW4+ea+DvDi6LmL39OhmizdzItPxK6hSj49ioSjRQGsVR2WCDpsxSdOP e7UL6QB7gcw6Fga2VjxGOPq1DXHGhY9mMyx7qlCPlVi9NbpvamJBQyf1/kWukb3islpl vH2PlUarAcqeLNmT9ZwdbE2t9zFfD3ygXnv2KYONKrHoQTrL74vIDG6V53za6Lxxg3w8 jU6vdoEb1ViftLJV+QZhOOHuTBo3WUlcK08dR2XGhDKUzb8vayailJn9KKigE83hxCR3 1HaA== X-Forwarded-Encrypted: i=1; AJvYcCU13ILF/uUbOF5oPeTdQoFDk2CXVnCWKXeMuE3B9JYKdfgl7v/y2ktS6OEjD0l18697zDMT7z1bP0G15M8=@vger.kernel.org X-Gm-Message-State: AOJu0Yzhco5lSDntboUa9O5kQ2vWMFRs5H505dBM41jQ688dh+rLMT75 6qyqFMQVy/slzGS2XNE1CQbz6A4J8HmAhYaVPvEzzO5nsdJpO6oUvKWY X-Gm-Gg: ATEYQzzVQiUb6IrSXGn8iQs6hGM/qiszHlkajOmGAofIK63vGYKB/33GFNLYU05wp+O xs31BPUAfdzzUpmSYpnJ9WQkDyuGTcX1AP83F2eKWv19Id2o697WzM/UwCa2dws8OMJn5iEeeN2 tI/zAruWSlBpkdG3RbCoNe5rIbY6skqglslb4CVe8/0TE8wJ7fY5KRl+fBZ6gNVyA3mUhL9zq4g PfKWXp2LVHjgnWBWfTFZfGHV+U190oE96DoekuLpLJYVV7D8AbcUo4ttPpsTX27wXtS1KPDybUw kWeiREqVN+88cN7F5fNZgSBaM8+ANjRiRlBVgyG0h33L2kW1q02NQ9FHUGCUhfviKqXQcLOeQRq ZCY82Jbvppeg8pOs0S8HDcVBhGzbzXs/Uwou0OUO9C52b8XgYjZexAC+jT8DbMQxlP/MAnEFJNN 3A2zfEJUrjK6Oyq7I4tvl+ut/FluCJlbX/AdzUkH86y8pqPXO4SwjKIMhf5vA+nAI2YHymryTje 0O+Dj5GHP+H5gLt X-Received: by 2002:a05:6214:2b06:b0:899:fad1:64e7 with SMTP id 6a1803df08f44-89a19d02056mr74295566d6.47.1772723399159; Thu, 05 Mar 2026 07:09:59 -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-89a0bb6e27asm64183176d6.2.2026.03.05.07.09.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 05 Mar 2026 07:09:58 -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 , Willem de Bruijn , Samiullah Khawaja , Hangbin Liu Cc: mike.marciniszyn@gmail.com, netdev@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH net-next v3 2/5] eth fbnic: Add register self test Date: Thu, 5 Mar 2026 10:09:44 -0500 Message-ID: <20260305150947.16893-3-mike.marciniszyn@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260305150947.16893-1-mike.marciniszyn@gmail.com> References: <20260305150947.16893-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 v3 - no changes 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) =20 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 @@ =20 #include =20 +struct fbnic_dev; + #define CSR_BIT(nr) (1u << (nr)) #define CSR_GENMASK(h, l) GENMASK(h, l) =20 @@ -1210,4 +1212,21 @@ enum{ FBNIC_CSR_VERSION_V1_0_ASIC =3D 1, }; =20 +/** + * 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) =20 +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; } } =20 @@ -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; } =20 +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, --=20 2.43.0 From nobody Thu Apr 9 21:57:29 2026 Received: from mail-qv1-f43.google.com (mail-qv1-f43.google.com [209.85.219.43]) (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 DD9233BED06 for ; Thu, 5 Mar 2026 15:10:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.219.43 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772723403; cv=none; b=jEDYkb52mpulxELCXrNPDDNnasFQltUuJUAReBTYHoHeOYAoiTEnw3QtwwUMHXSZV3qJTcPW/Vdl9XCT+lb2Ix6HK/PxcVFCxwus1u7oK7/qKi56u7op3kTgSIeIncs7hyYc1iTpoSGXzG0eNy29jqAJleeDPWQWa6R1nsBYo4E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772723403; c=relaxed/simple; bh=yyyMHGSXgdkMMe94GxjZiUKE6PWiz58uwyNAnyENJ6I=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ILWJjqBG/IX5HjVwr1Y1JVSFtHuVWecSar9sk+T4tJet6BUG5ZWzOLo+bbmQJWjR38lmbqpAvQJlIUKMQWNeS3cEHKIV5hFQx0TmDn70NmmGSgoZoP4vgIkCFpQiCw3g5NecisGeVzUc9cjSTJ4C4g9DjBZTWLKCppNw+uzRAxk= 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=OQMaPK2G; arc=none smtp.client-ip=209.85.219.43 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="OQMaPK2G" Received: by mail-qv1-f43.google.com with SMTP id 6a1803df08f44-89a133cdd4aso32873796d6.0 for ; Thu, 05 Mar 2026 07:10:01 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1772723401; x=1773328201; 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=6E+8lYIDyjyWKE4ZMwjF3RTtZvW/g7ABeCeR/wgYGj4=; b=OQMaPK2GntmAz9NzC8AEbwGKi+8IxKzVdGI/9lfunQ0VPvX+UEk+SW4rCQA7X0EPPo dZrOA7RIfY4UnRzSR7GK8pWUBJ4ngDByIr6H4D/s8RF1+rqaJnNVSrQbmKVlouszoacf WuOjlJd6iRfc2PKqW1c2COlwn6qJ7K5C6f5oLHSJsCMpjiG4Oh9Us1L6x4wktdvXs+Uq xm6NPlEHRUGX59vnXYn56i/sOtmv3noulzCBsvmBw8GiycWTglFMbYxudFTJIF2abV+u wVErZ+eI41BCtEfEXSNf39+yNyZc8XY2lY+Y0JX4RXSCO+jYs7tFlZ+f9pG0WrsFhb5d SWmg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772723401; x=1773328201; 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=6E+8lYIDyjyWKE4ZMwjF3RTtZvW/g7ABeCeR/wgYGj4=; b=w3Dvvvghf7/knZUVWb87EiryP8AWrC+FjE8EYmrghi4ACjwlvlgR9vUIxGC5RZjkrL 2wZLFp4RJeo9kELS8EAyj4vQeFuE8h1SMrLYATFF5c9G831B4aQZ3AwntONNypsPJjW5 hOuJZudh4vup6wTkr9YCLK096GmkecMJjsaH9j2L142dTsxTXnr3RFM7tmg0UXECO67u zX8oO4eBTd4aHv2s8CUNz+8VzJUK4ejmPBtqyOSxq826KOLLXe1Ytps4R9uJptVMUDra +IOdaRq6lN+Z6664ts4VjGUlr0Gr5dhpYpEW2x+0G6zxVQ18TT87uMZPBYDNIFJZc5E5 Y2/A== X-Forwarded-Encrypted: i=1; AJvYcCWs0T8nwwwoDaaZEu6LFLYbnYPLDkc2mZ6UYAk9bHvcqZ3r5xgD47Q82G40S1i7/X4fc16kFhKcLGR7gkk=@vger.kernel.org X-Gm-Message-State: AOJu0YwopOycdL42b9NBNKWJAGzAwt1LW0bMfqscGQZZBJVNq0fst/xT odMvvGQAdoxoC8ta7Kvi1HjKIiQ5EDROjqPLu1J6FaGGvONJ6zN289D6 X-Gm-Gg: ATEYQzyp0Ryh/hOV+w469VXEni+Hw4hPIjD4CVFk3JzsRQc6DiPr6KKpbfDgqPudhgX ZBGzHFZPCWP+t4jZX+jNBATa4c+GsTqJAxw8/aVWYYizzHelNnnskc3x2ZNaPSjewB41q7aNHrd TYxD6EGJ2Y/kvrkOm06QD1bRpotl1RXmDKrLnS7q9bZWeEASuZPrS/un0Lbrt0M+T0qeIMSxcjx G/lZB3+3/bykd4ZB5EvoRbYR2FEQfLMXbu5MsmehL9jraon7zdb7kXUMz7ZRVfBgg32X3HwsJZj Td8WhPNE18RQdDIXgLxiwY8ZeV2ICgy69ui2qEC8bY583EKmlv+J71opvh5FLkSCZ2KpWOF63Ov aAJBvuDvDbqJpaRutUbQE/6mdoRkj/fdX4O0oxmbeTFwqGFEqOB51mHp+JEBmJrGsrGKByGmyxY 7t7lIeK+00GRMQIKETqBRdoo0qF0cYhVQV20vbsbiwO1tF/Ayxd53TpVGbA8fokYgFdxPtrBtJW 1o+VsvDYzKdHj0M7ZShxvFbK0E= X-Received: by 2002:ad4:5d6f:0:b0:899:fd8c:55ca with SMTP id 6a1803df08f44-89a19ac9c9fmr90536686d6.29.1772723400552; Thu, 05 Mar 2026 07:10:00 -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-89a0bb6e27asm64183176d6.2.2026.03.05.07.09.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 05 Mar 2026 07:10:00 -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 , Willem de Bruijn , Samiullah Khawaja , Hangbin Liu Cc: mike.marciniszyn@gmail.com, netdev@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH net-next v3 3/5] eth fbnic: Add msix self test Date: Thu, 5 Mar 2026 10:09:45 -0500 Message-ID: <20260305150947.16893-4-mike.marciniszyn@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260305150947.16893-1-mike.marciniszyn@gmail.com> References: <20260305150947.16893-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 v3 - add missing enum 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, 214 insertions(+) diff --git a/drivers/net/ethernet/meta/fbnic/fbnic.h b/drivers/net/ethernet= /meta/fbnic/fbnic.h index 779a083b9215..534caa3c872d 100644 --- a/drivers/net/ethernet/meta/fbnic/fbnic.h +++ b/drivers/net/ethernet/meta/fbnic/fbnic.h @@ -194,6 +194,38 @@ 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 + * @FBNIC_TEST_MSIX_BITS_SET_AFTER_TEST: Bits are set after test + */ +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, + FBNIC_TEST_MSIX_BITS_SET_AFTER_TEST =3D 70, +}; + +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); =20 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 { =20 enum fbnic_self_test_results { TEST_REG =3D 0, + TEST_MSIX, }; =20 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)", }; =20 #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; } =20 +/** + * 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, =20 if (!(eth_test->flags & ETH_TEST_FL_OFFLINE)) { data[TEST_REG] =3D 0; + data[TEST_MSIX] =3D 0; return; } =20 @@ -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; =20 + 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..44034d53112c 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); } =20 +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 FBNIC_TEST_MSIX_BITS_SET_AFTER_TEST; + + /* 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; --=20 2.43.0 From nobody Thu Apr 9 21:57:29 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 7F8B639C63E for ; Thu, 5 Mar 2026 15:10:03 +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=1772723405; cv=none; b=HI0N728oxZQ3m+MPqGx+PE6hf3d93hvasS8JRWLIclGqB/9pFfS5s2hKJiIakok8KLsRL02oH1UKaqCuXulXxAyRHGSOCkc/9P7J2MjcRgTR182ycDhFT3JLw2d/SzFovIWXZYiSn0qqvNyPfBN0Dai8yX0u++EDZxvYV0rt7dw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772723405; c=relaxed/simple; bh=PcQq9g6NfojfsPV8CHZBJ1Tkrtkx9yrgmjpx4/IuMPI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=E5xrNfJPJ+Sx9LQbMZ0WFj8hRkcfczwd5iiIW1GFYXeLn4O0+EWG0aIZzelI8kc0cyHYcg8lciCj1TV5kw8Rm2t8Rx3Ji4xN6eRNDibqeddPUAAn2cqRiEE1tMouwZzSR8obKwFc6PwKVhzPZ4n4XOhd0/bMvHc6I0/6ogFvP40= 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=Be5CMTAF; 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="Be5CMTAF" Received: by mail-qk1-f169.google.com with SMTP id af79cd13be357-8cb7edbcde6so994649785a.3 for ; Thu, 05 Mar 2026 07:10:03 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1772723402; x=1773328202; 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=GtF+Rx1AC6n6+KaazXzEFIVkqD/mdgTa08+v0sCjj2I=; b=Be5CMTAFyLsOeSk97RkMgKQTWbtVdbZaW/nU3BPRl+V5UjQxDpTDTvaOEaxFSqISjF 6GURXswU23BqKNxb3H59TnsncPgjZ+EUCkgfkkZREuxbMy6BsbcyxBFsqcyw5PxfYnq8 wxMRgwD2DPFyi+efPBMeokmjMcP08ITR3jAcPqDLQOoeptbhL6RXxdN9tHmcYKCaudcJ kZvRncXo14btnDOIukw69uDtNEWf8WgioaB/Wnj5/P7j66aPnVV2Ye3DSQZtDp51SekP 36Ctu9JFb9PXrywMNi8J1EiyAEaJ8hWjT8QFD6KpToY36ypHh++J59jY1mmgjVtVNKsn aAZg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772723402; x=1773328202; 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=GtF+Rx1AC6n6+KaazXzEFIVkqD/mdgTa08+v0sCjj2I=; b=AT2vhWDmUvPK2i3BX4bCyTxY//0aDyapU/H1EIpAykQWgXfB60NdKiaBoTXDrjm3FG Mt2jiqNH3yJ3fDPvH0sLnPPiXoJAzhvvN5mbZsBM52zQ4jAbfED0P8j+hRt0ufuTRLpa 4VQKxLH4XGdv1evXmLoq4H3WPvJPYtyTzkOodvEIG5nGngGssUwMrOFtAHLqx8Grf54k YgFK7xZwBnjNNNWQLCvBSErl2yBWO+RMxh4l2/9wvdAiUBUvSAIl66iB5PjWXSrVEDWV xxpZYGxNqG0C0BF0GRxMQE4mSrXzd+3aT3OKA6ydnjV1GjP5vyR12Uh7Sz+3XyfCmG3j d5jg== X-Forwarded-Encrypted: i=1; AJvYcCWgPrBtJJnfk6G6iO/joWbmlEpO3OVOzaK0BgEzockHoWbVG/gHmmYeBMOfz9qrgg7JljOa/mYxly2rnRo=@vger.kernel.org X-Gm-Message-State: AOJu0YyQsPagD1UfMBr4Jpa6kOXNE2J81ee+me9shheBPqqXfUWe7NYF 59oyVyX6LLsKeRp5OO5gN3ZoesjDfaAki0045O1VyKE9jFrG4929Ttdg X-Gm-Gg: ATEYQzzvzbr20YUxTc+UrpacmtAVE0YesMoUbBEj7s/TWFmLwYTMAThLyEmt0O9dqJs 5A/l6WHCfiK4VNBe3xpHWi7SQ2NFIPsyKJM1oEL6c89glLJs6bFdhTa8GEKPUBlbt800Xsff8oL SomY5qqZInx8sfmeaf4cr1+7hcu2vOiuHP8jd9cEyWL9MFJh0I4k1s0afezlWupoo10ylfhI1SV vrAO8qn7Zf4JpOJsb+7N9PHYNXYGAiwlK4+buOGZ59ptPJFdhyvNSG5TRR2x7OByFXZLSTsYQ9i HY05XdnJkKwhkTKnPWW4kkKWZgnKW5VwM91qOsgRBXQasukyody5UpxvO/jSAPD1oBY8qfA+ACK hBYLECZTY9twR/7WFO1d2vEq4Agqy+cMIl1HMcA9Qyzz1x7a1+31qbX9hjDpoCDgmIK/0/wFC9P /GD9Un1cTwQDxyHpv7ThZsbK0rinnztyJGa+2hUQ2f3xgMKl5a782JCX5DpTNGzxsa6+QMdIjah d6oRMRbD2Or0Ie3 X-Received: by 2002:a05:620a:1726:b0:8c7:ad9:d0a2 with SMTP id af79cd13be357-8cd6af73a7fmr19002185a.22.1772723402074; Thu, 05 Mar 2026 07:10:02 -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-89a0bb6e27asm64183176d6.2.2026.03.05.07.10.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 05 Mar 2026 07:10:01 -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 , Willem de Bruijn , Samiullah Khawaja , Hangbin Liu Cc: mike.marciniszyn@gmail.com, netdev@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH net-next v3 4/5] eth fbnic: TLV support for use by MBX self test Date: Thu, 5 Mar 2026 10:09:46 -0500 Message-ID: <20260305150947.16893-5-mike.marciniszyn@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260305150947.16893-1-mike.marciniszyn@gmail.com> References: <20260305150947.16893-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 v3 - no changes 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; } =20 +#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 =20 +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) =20 +#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_ */ --=20 2.43.0 From nobody Thu Apr 9 21:57:29 2026 Received: from mail-qv1-f48.google.com (mail-qv1-f48.google.com [209.85.219.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 1769E3BED4A for ; Thu, 5 Mar 2026 15:10:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.219.48 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772723407; cv=none; b=e8t7QbHoReaAkvEeWdbaKBjN2L3WF3VEoVB8drlEQCJXfF72/Lptxe6IOkOl8sQbZ4UOoIOhCcp8I6VmdoYXcnhyjw0uMj7SfK5u9wnjJENrcZLxbebR5GAXsJwyLXA/iYqztOsw8JfAaNqHBPh3+KI6DeamdfRABuWR8QKJ/0Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772723407; c=relaxed/simple; bh=G0Gbsy/4+Z7L57ZxL288jEXgvc4nxW4a2lkG97ek/tU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Y02H6c+ERiNJawcrjdCgUDokMRKJEIUNDPR+ISIEB5s0jHKV0rnsorukVqkHKRdb3uRwKGkeC8E1Vioox0ELtO8z5FlQk6dlXaVcMdS4iK3SmajSQGdC9Zz2z9+i3DgNdu+NQD71/gJGK3+FqEvgiySR3ZaAr0Dc6vO43FI9UhQ= 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=a91Z0cOI; arc=none smtp.client-ip=209.85.219.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="a91Z0cOI" Received: by mail-qv1-f48.google.com with SMTP id 6a1803df08f44-899fb030812so63492276d6.2 for ; Thu, 05 Mar 2026 07:10:04 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1772723404; x=1773328204; 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=yGq/SGkUnWkPEv9Q6uJkwsdq8YtqalI2CxU9i4Sx8jA=; b=a91Z0cOIlSx1VjFSYNDKkwP+ePX6OCFL8/mwnn2Kv861zAPnMktgsd4ukIqGiuuFIx OXuxqmycG4Shii/WT9ME4LUOHkdzLIWQdHdRqcWxSKCXzKU0fRiQJHEprNP77QVeMFhO H83skBroMF3CCWuvlyBg8/LSpTRzKde50IAxzLHf6UXwzxkZZ5DYd6Yw+kmhSylpJMGf rLzdyW9zn4s0ahSILFXfyzPU1yLZPZnyDNt/OkvdNrOkGr2GakAcCiPNt57UvtRT63qQ rgbVjkALDYm7fc8WvJzcRxuSdFamF72sN03nKcepgrBQ3Sfv5cyPr9o1wrnTLhpcl1Ep cnXg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772723404; x=1773328204; 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=yGq/SGkUnWkPEv9Q6uJkwsdq8YtqalI2CxU9i4Sx8jA=; b=KXy34TSYqvgYhkmNL6oiqi8/UWXW1VBNnFZwNxJBuiHe3ZaqgKRw9UEb2g3sT5rQYY CiQ42XiupTvfPWvPgkiOdZ68gPCXnEBJDFHpQsoGgLJaHKoCY6oLr4l9TxxFoBY57dlj YTpwA11GxwMo2z25yJ0Z1B5+Quh4UxlZ9RrPufmBM/PPKrr4Gc/un46uT7GRcUzUWiII /MzAQy/35BRUzwfSNP7WlEtyoa5gnmDFzlw1VgJd+kIwC0WBTpDuRWcq8ovCmeaDQ5Zr /0HyYSGrlY49pZ4SHhigdh273qR6MFCVSK5WsOi9TPJqVyDsQdnisEUPKq7b93DAurTl HmNw== X-Forwarded-Encrypted: i=1; AJvYcCXWvrA/1bcLoMReEv1Qe0hoHZtlDfRTJAMrQJ3Elz9CYCMYrH2D429kEE/SRiRbP6pfurgXR60V0btBu/Y=@vger.kernel.org X-Gm-Message-State: AOJu0YwDIdVAr3IQhzLDbaVS/LIdI8qDwwfp2ISC18G7GLA2WwIiXbGs LZivsEUK6q4inlceoFSYXQVX5gZElSGQn4Qot2jgCjv+64fcAVdFddZH X-Gm-Gg: ATEYQzwx2eUeIyAJT3GeEfT4Zhf+XK3FTYaGOCzgmGlf093L4qoB+rC/nNKvYvRAKl5 mLaxCe+SjNaJqg1xoMcqgg8Uij4wVsUKny5YH6MWCOz/RL72enp7MKdcJNWAO1oRPmPi2eaAcl3 YpDw1JeaZYgej32gmFYgpSndVuezt0mRSduXKqLM8GtYZix/usLGQHdEi0UIUrlxY9J2+IlNZNs Jxj2lgJUy4L+7/wcwBh88pZtjNVY4FmrTSyu4hcYJblOHKYkacW5zbN+1RBqYb10tRe94Y0trho BTnjNGixyZin9Ai+zy8ipuSq8JWWTWQSw43Dp8Pounf+JC34tisCSZtL5n5Gl13R1SXmM2QecTC iI9oaPtzyYaYjWqlt5NBr7om7rORtVGdL+Ang+kBS/piqtTeeoupplV0e+jceQUZY+Y1naxLP4u SoXn2fA1HDXWF3N8L5v0B6A2EJ+6TZDCeC9LMRe5T5SiBxbexl70DxzojnAaJSmvRumUPElj+AC mC9WJErUMmQ76Dr X-Received: by 2002:ad4:5ce6:0:b0:899:efd1:9e15 with SMTP id 6a1803df08f44-89a2e031eb2mr1649216d6.49.1772723403489; Thu, 05 Mar 2026 07:10:03 -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-89a0bb6e27asm64183176d6.2.2026.03.05.07.10.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 05 Mar 2026 07:10:02 -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 , Willem de Bruijn , Samiullah Khawaja , Hangbin Liu Cc: mike.marciniszyn@gmail.com, netdev@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH net-next v3 5/5] eth fbnic: Add mailbox self test Date: Thu, 5 Mar 2026 10:09:47 -0500 Message-ID: <20260305150947.16893-6-mike.marciniszyn@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260305150947.16893-1-mike.marciniszyn@gmail.com> References: <20260305150947.16893-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 v3 - no changes 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, }; =20 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)", }; =20 #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; } =20 +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); =20 + 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; } =20 +/** + * 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; } =20 +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)); } =20 +/** + * 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); --=20 2.43.0