[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20260206154246.814-6-mike.marciniszyn@gmail.com>
Date: Fri, 6 Feb 2026 10:42:45 -0500
From: mike.marciniszyn@...il.com
To: Alexander Duyck <alexanderduyck@...com>,
Jakub Kicinski <kuba@...nel.org>,
kernel-team@...a.com,
Andrew Lunn <andrew+netdev@...n.ch>,
"David S. Miller" <davem@...emloft.net>,
Eric Dumazet <edumazet@...gle.com>,
Paolo Abeni <pabeni@...hat.com>,
Simon Horman <horms@...nel.org>,
Russell King <linux@...linux.org.uk>,
Jacob Keller <jacob.e.keller@...el.com>,
Mohsin Bashir <mohsin.bashr@...il.com>,
Lee Trager <lee@...ger.us>,
"Mike Marciniszyn (Meta)" <mike.marciniszyn@...il.com>,
Dan Carpenter <dan.carpenter@...aro.org>,
Pei Xiao <xiaopei01@...inos.cn>,
Stanislav Fomichev <sdf@...ichev.me>,
Kuniyuki Iwashima <kuniyu@...gle.com>,
Samiullah Khawaja <skhawaja@...gle.com>,
Ahmed Zaki <ahmed.zaki@...el.com>,
Alexander Lobakin <aleksander.lobakin@...el.com>
Cc: netdev@...r.kernel.org,
linux-kernel@...r.kernel.org
Subject: [PATCH net-next v12 5/5] eth fbnic: Add mailbox self test
From: "Mike Marciniszyn (Meta)" <mike.marciniszyn@...il.com>
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) <mike.marciniszyn@...il.com>
---
.../net/ethernet/meta/fbnic/fbnic_ethtool.c | 15 +++
drivers/net/ethernet/meta/fbnic/fbnic_fw.c | 92 +++++++++++++++++++
drivers/net/ethernet/meta/fbnic/fbnic_fw.h | 3 +
3 files changed, 110 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_stats[] = {
enum fbnic_self_test_results {
TEST_REG = 0,
TEST_MSIX,
+ TEST_MBX,
};
static const char fbnic_gstrings_self_test[][ETH_GSTRING_LEN] = {
[TEST_REG] = "Register test (offline)",
[TEST_MSIX] = "MSI-X Interrupt test (offline)",
+ [TEST_MBX] = "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_device *netdev, u64 *data)
return !!*data;
}
+static int fbnic_ethtool_mbx_self_test(struct net_device *netdev, u64 *data)
+{
+ struct fbnic_net *fbn = netdev_priv(netdev);
+ struct fbnic_dev *fbd = fbn->fbd;
+
+ *data = 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 = netif_running(netdev);
+ if (fbnic_ethtool_mbx_self_test(netdev, &data[TEST_MBX]))
+ eth_test->flags |= ETH_TEST_FL_FAILED;
+
if (!(eth_test->flags & ETH_TEST_FL_OFFLINE)) {
data[TEST_REG] = 0;
data[TEST_MSIX] = 0;
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_fw.c b/drivers/net/ethernet/meta/fbnic/fbnic_fw.c
index 1f0b6350bef4..0fb8dc9091ca 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 msg_type)
return cmpl_data;
}
+/**
+ * fbnic_fw_xmit_test_msg - Create and transmit a test message to FW mailbox
+ * @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 = fbnic_tlv_test_create(fbd);
+ if (!test_msg)
+ return -ENOMEM;
+
+ err = 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, bool 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 = opaque;
+ int err;
+
+ /* find cmpl */
+ cmpl = fbnic_fw_get_cmpl_by_type(fbd, FBNIC_TLV_MSG_ID_TEST);
+ if (!cmpl)
+ return -ENOSPC;
+
+ err = fbnic_tlv_parser_test(opaque, results);
+
+ cmpl->result = err;
+ complete(&cmpl->done);
+ fbnic_fw_put_cmpl(cmpl);
+
+ return err;
+}
+
static const struct fbnic_tlv_parser fbnic_fw_tlv_parser[] = {
+ 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,45 @@ void fbnic_mbx_flush_tx(struct fbnic_dev *fbd)
} while (time_is_after_jiffies(timeout));
}
+int fbnic_fw_mbx_self_test(struct fbnic_dev *fbd)
+{
+ struct fbnic_fw_completion *cmpl;
+ int err;
+
+ /* Skip test if FW interface is not present */
+ if (!fbnic_fw_present(fbd))
+ return 10;
+
+ cmpl = fbnic_fw_alloc_cmpl(FBNIC_TLV_MSG_ID_TEST);
+ if (!cmpl)
+ return 20;
+
+ /* Load a test message onto the FW mailbox interface
+ * and arm the completion.
+ */
+ err = fbnic_fw_xmit_test_msg(fbd, cmpl);
+ if (err) {
+ err = 30;
+ goto exit_free;
+ }
+
+ /* Verify we received a message back */
+ if (!fbnic_mbx_wait_for_cmpl(cmpl)) {
+ err = 40;
+ goto exit_cleanup;
+ }
+
+ /* Verify there were no parsing errors */
+ if (cmpl->result)
+ err = 50;
+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/ethernet/meta/fbnic/fbnic_fw.h
index 8f7218900562..054d8f104486 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_fw.h
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_fw.h
@@ -104,6 +104,9 @@ 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);
+int 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
Powered by blists - more mailing lists