* [PATCH net-next v5 0/5] eth: fbnic: Add devlink dev flash support
@ 2025-05-12 18:53 Lee Trager
2025-05-12 18:53 ` [PATCH net-next v5 1/5] pldmfw: Don't require send_package_data or send_component_table to be defined Lee Trager
` (5 more replies)
0 siblings, 6 replies; 12+ messages in thread
From: Lee Trager @ 2025-05-12 18:53 UTC (permalink / raw)
To: Alexander Duyck, Jakub Kicinski, kernel-team, David S. Miller,
Eric Dumazet, Paolo Abeni, Simon Horman, Jonathan Corbet,
Andrew Lunn, Jacob Keller, Mohsin Bashir, Sanman Pradhan, Su Hui,
Lee Trager, Al Viro
Cc: Andrew Lunn, netdev, linux-doc, linux-kernel
fbnic supports updating firmware using signed PLDM images. PLDM images are
written into the flash. Flashing does not interrupt the operation of the
device.
Changes:
V5:
* Make sure fbnic_pldm_match_record() always returns a bool
V4 - https://lore.kernel.org/netdev/20250510002851.3247880-1-lee@trager.us/T/#t
* Tested flashing in a 50x loop
* Add devl_lock() in shutdown / quiescene paths like suspend to prevent
interrupting the FW flashing process.
* Add support for multiple completion messages.
* Removed BSD function notation from fbnic_fw_xmit_fw_start_upgrade()
* Mailbox functions no longer return cmpl_data->result
* Add missing error check in fbnic_fw_xmit_fw_write
* Drop setting cmpl->u.fw_update.* to 0
* Set offset and length before validation
* Drop !fw check
* Firmware upgrades are now process driven
* Fix potential memory leak when an error is received in the mailbox when
updating.
* Include anti-rollback support
* Drop retries when updating but increase timeout to 10s
* Use NL_SET_ERR_MSG_FMT_MOD in fbnic_devlink_flash_update()
* Updated cover letter, commit messages, and docs as suggested
* Dropped kdocs
* Patched libpldmfw to not require send_package_data or send_component_table
which allowed stub functions to be dropped.
* Dropped all dev_*() printks
* Fixed Xmas tree variable declarations
V3 - https://lore.kernel.org/lkml/20241111043058.1251632-1-lee@trager.us/T/
* Fix comments
V2 - https://lore.kernel.org/all/20241022013941.3764567-1-lee@trager.us/
* Fixed reversed Xmas tree variable declarations
* Replaced memcpy with strscpy
Lee Trager (5):
pldmfw: Don't require send_package_data or send_component_table to be
defined
eth: fbnic: Accept minimum anti-rollback version from firmware
eth: fbnic: Add support for multiple concurrent completion messages
eth: fbnic: Add mailbox support for PLDM updates
eth: fbnic: Add devlink dev flash support
.../device_drivers/ethernet/meta/fbnic.rst | 11 +
drivers/net/ethernet/meta/Kconfig | 1 +
drivers/net/ethernet/meta/fbnic/fbnic.h | 3 +-
.../net/ethernet/meta/fbnic/fbnic_devlink.c | 260 +++++++++++++++-
drivers/net/ethernet/meta/fbnic/fbnic_fw.c | 294 ++++++++++++++++--
drivers/net/ethernet/meta/fbnic/fbnic_fw.h | 53 +++-
drivers/net/ethernet/meta/fbnic/fbnic_mac.c | 2 +-
drivers/net/ethernet/meta/fbnic/fbnic_pci.c | 9 +
lib/pldmfw/pldmfw.c | 6 +
9 files changed, 616 insertions(+), 23 deletions(-)
--
2.47.1
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH net-next v5 1/5] pldmfw: Don't require send_package_data or send_component_table to be defined
2025-05-12 18:53 [PATCH net-next v5 0/5] eth: fbnic: Add devlink dev flash support Lee Trager
@ 2025-05-12 18:53 ` Lee Trager
2025-05-12 19:08 ` Jacob Keller
2025-05-12 18:53 ` [PATCH net-next v5 2/5] eth: fbnic: Accept minimum anti-rollback version from firmware Lee Trager
` (4 subsequent siblings)
5 siblings, 1 reply; 12+ messages in thread
From: Lee Trager @ 2025-05-12 18:53 UTC (permalink / raw)
To: Alexander Duyck, Jakub Kicinski, kernel-team, David S. Miller,
Eric Dumazet, Paolo Abeni, Simon Horman, Jonathan Corbet,
Andrew Lunn, Jacob Keller, Mohsin Bashir, Sanman Pradhan, Su Hui,
Lee Trager, Al Viro
Cc: Andrew Lunn, netdev, linux-doc, linux-kernel
Not all drivers require send_package_data or send_component_table when
updating firmware. Instead of forcing drivers to implement a stub allow
these functions to go undefined.
Signed-off-by: Lee Trager <lee@trager.us>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Reviewed-by: Simon Horman <horms@kernel.org>
---
lib/pldmfw/pldmfw.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/lib/pldmfw/pldmfw.c b/lib/pldmfw/pldmfw.c
index 6264e2013f25..b45ceb725780 100644
--- a/lib/pldmfw/pldmfw.c
+++ b/lib/pldmfw/pldmfw.c
@@ -728,6 +728,9 @@ pldm_send_package_data(struct pldmfw_priv *data)
struct pldmfw_record *record = data->matching_record;
const struct pldmfw_ops *ops = data->context->ops;
+ if (!ops->send_package_data)
+ return 0;
+
return ops->send_package_data(data->context, record->package_data,
record->package_data_len);
}
@@ -755,6 +758,9 @@ pldm_send_component_tables(struct pldmfw_priv *data)
if (!test_bit(index, bitmap))
continue;
+ if (!data->context->ops->send_component_table)
+ continue;
+
/* determine whether this is the start, middle, end, or both
* the start and end of the component tables
*/
--
2.47.1
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH net-next v5 2/5] eth: fbnic: Accept minimum anti-rollback version from firmware
2025-05-12 18:53 [PATCH net-next v5 0/5] eth: fbnic: Add devlink dev flash support Lee Trager
2025-05-12 18:53 ` [PATCH net-next v5 1/5] pldmfw: Don't require send_package_data or send_component_table to be defined Lee Trager
@ 2025-05-12 18:53 ` Lee Trager
2025-05-12 18:53 ` [PATCH net-next v5 3/5] eth: fbnic: Add support for multiple concurrent completion messages Lee Trager
` (3 subsequent siblings)
5 siblings, 0 replies; 12+ messages in thread
From: Lee Trager @ 2025-05-12 18:53 UTC (permalink / raw)
To: Alexander Duyck, Jakub Kicinski, kernel-team, David S. Miller,
Eric Dumazet, Paolo Abeni, Simon Horman, Jonathan Corbet,
Andrew Lunn, Jacob Keller, Mohsin Bashir, Sanman Pradhan, Su Hui,
Lee Trager, Al Viro
Cc: Andrew Lunn, netdev, linux-doc, linux-kernel
fbnic supports applying firmware which may not be rolled back. This is
implemented in firmware however it is useful for the driver to know the
minimum supported firmware version. This will enable the driver validate
new firmware before it is sent to the NIC. If it is too old the driver can
provide a clear message that the version is too old.
Signed-off-by: Lee Trager <lee@trager.us>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Reviewed-by: Simon Horman <horms@kernel.org>
---
drivers/net/ethernet/meta/fbnic/fbnic_fw.c | 4 ++++
drivers/net/ethernet/meta/fbnic/fbnic_fw.h | 2 ++
2 files changed, 6 insertions(+)
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_fw.c b/drivers/net/ethernet/meta/fbnic/fbnic_fw.c
index 3d9636a6c968..e4f72fb730a6 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_fw.c
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_fw.c
@@ -464,6 +464,7 @@ static const struct fbnic_tlv_index fbnic_fw_cap_resp_index[] = {
FBNIC_TLV_ATTR_U32(FBNIC_FW_CAP_RESP_UEFI_VERSION),
FBNIC_TLV_ATTR_STRING(FBNIC_FW_CAP_RESP_UEFI_COMMIT_STR,
FBNIC_FW_CAP_RESP_COMMIT_MAX_SIZE),
+ FBNIC_TLV_ATTR_U32(FBNIC_FW_CAP_RESP_ANTI_ROLLBACK_VERSION),
FBNIC_TLV_ATTR_LAST
};
@@ -586,6 +587,9 @@ static int fbnic_fw_parse_cap_resp(void *opaque, struct fbnic_tlv_msg **results)
if (results[FBNIC_FW_CAP_RESP_BMC_ALL_MULTI] || !bmc_present)
fbd->fw_cap.all_multi = all_multi;
+ fbd->fw_cap.anti_rollback_version =
+ fta_get_uint(results, FBNIC_FW_CAP_RESP_ANTI_ROLLBACK_VERSION);
+
return 0;
}
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_fw.h b/drivers/net/ethernet/meta/fbnic/fbnic_fw.h
index a3618e7826c2..692dfd8746e7 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_fw.h
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_fw.h
@@ -42,6 +42,7 @@ struct fbnic_fw_cap {
u8 all_multi : 1;
u8 link_speed;
u8 link_fec;
+ u32 anti_rollback_version;
};
struct fbnic_fw_completion {
@@ -122,6 +123,7 @@ enum {
FBNIC_FW_CAP_RESP_STORED_CMRT_COMMIT_STR = 0x10,
FBNIC_FW_CAP_RESP_UEFI_VERSION = 0x11,
FBNIC_FW_CAP_RESP_UEFI_COMMIT_STR = 0x12,
+ FBNIC_FW_CAP_RESP_ANTI_ROLLBACK_VERSION = 0x15,
FBNIC_FW_CAP_RESP_MSG_MAX
};
--
2.47.1
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH net-next v5 3/5] eth: fbnic: Add support for multiple concurrent completion messages
2025-05-12 18:53 [PATCH net-next v5 0/5] eth: fbnic: Add devlink dev flash support Lee Trager
2025-05-12 18:53 ` [PATCH net-next v5 1/5] pldmfw: Don't require send_package_data or send_component_table to be defined Lee Trager
2025-05-12 18:53 ` [PATCH net-next v5 2/5] eth: fbnic: Accept minimum anti-rollback version from firmware Lee Trager
@ 2025-05-12 18:53 ` Lee Trager
2025-05-12 19:08 ` Jacob Keller
2025-05-12 18:54 ` [PATCH net-next v5 4/5] eth: fbnic: Add mailbox support for PLDM updates Lee Trager
` (2 subsequent siblings)
5 siblings, 1 reply; 12+ messages in thread
From: Lee Trager @ 2025-05-12 18:53 UTC (permalink / raw)
To: Alexander Duyck, Jakub Kicinski, kernel-team, David S. Miller,
Eric Dumazet, Paolo Abeni, Simon Horman, Jonathan Corbet,
Andrew Lunn, Jacob Keller, Mohsin Bashir, Sanman Pradhan, Su Hui,
Lee Trager, Al Viro
Cc: Andrew Lunn, netdev, linux-doc, linux-kernel
Extend fbnic mailbox to support multiple concurrent completion messages at
once. This enables fbnic to support running multiple operations at once
which depend on a response from firmware via the mailbox.
Signed-off-by: Lee Trager <lee@trager.us>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Reviewed-by: Simon Horman <horms@kernel.org>
---
drivers/net/ethernet/meta/fbnic/fbnic.h | 3 +-
drivers/net/ethernet/meta/fbnic/fbnic_fw.c | 99 +++++++++++++++++----
drivers/net/ethernet/meta/fbnic/fbnic_fw.h | 5 +-
drivers/net/ethernet/meta/fbnic/fbnic_mac.c | 2 +-
4 files changed, 87 insertions(+), 22 deletions(-)
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic.h b/drivers/net/ethernet/meta/fbnic/fbnic.h
index ad01ed05d78b..65815d4f379e 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic.h
+++ b/drivers/net/ethernet/meta/fbnic/fbnic.h
@@ -19,6 +19,7 @@
struct fbnic_napi_vector;
#define FBNIC_MAX_NAPI_VECTORS 128u
+#define FBNIC_MBX_CMPL_SLOTS 4
struct fbnic_dev {
struct device *dev;
@@ -42,7 +43,7 @@ struct fbnic_dev {
struct fbnic_fw_mbx mbx[FBNIC_IPC_MBX_INDICES];
struct fbnic_fw_cap fw_cap;
- struct fbnic_fw_completion *cmpl_data;
+ struct fbnic_fw_completion *cmpl_data[FBNIC_MBX_CMPL_SLOTS];
/* Lock protecting Tx Mailbox queue to prevent possible races */
spinlock_t fw_tx_lock;
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_fw.c b/drivers/net/ethernet/meta/fbnic/fbnic_fw.c
index e4f72fb730a6..6fcba4e8c21e 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_fw.c
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_fw.c
@@ -237,6 +237,44 @@ static int fbnic_mbx_map_tlv_msg(struct fbnic_dev *fbd,
return err;
}
+static int fbnic_mbx_set_cmpl_slot(struct fbnic_dev *fbd,
+ struct fbnic_fw_completion *cmpl_data)
+{
+ struct fbnic_fw_mbx *tx_mbx = &fbd->mbx[FBNIC_IPC_MBX_TX_IDX];
+ int free = -EXFULL;
+ int i;
+
+ if (!tx_mbx->ready)
+ return -ENODEV;
+
+ for (i = 0; i < FBNIC_MBX_CMPL_SLOTS; i++) {
+ if (!fbd->cmpl_data[i])
+ free = i;
+ else if (fbd->cmpl_data[i]->msg_type == cmpl_data->msg_type)
+ return -EEXIST;
+ }
+
+ if (free == -EXFULL)
+ return -EXFULL;
+
+ fbd->cmpl_data[free] = cmpl_data;
+
+ return 0;
+}
+
+static void fbnic_mbx_clear_cmpl_slot(struct fbnic_dev *fbd,
+ struct fbnic_fw_completion *cmpl_data)
+{
+ int i;
+
+ for (i = 0; i < FBNIC_MBX_CMPL_SLOTS; i++) {
+ if (fbd->cmpl_data[i] == cmpl_data) {
+ fbd->cmpl_data[i] = NULL;
+ break;
+ }
+ }
+}
+
static void fbnic_mbx_process_tx_msgs(struct fbnic_dev *fbd)
{
struct fbnic_fw_mbx *tx_mbx = &fbd->mbx[FBNIC_IPC_MBX_TX_IDX];
@@ -258,6 +296,19 @@ static void fbnic_mbx_process_tx_msgs(struct fbnic_dev *fbd)
tx_mbx->head = head;
}
+int fbnic_mbx_set_cmpl(struct fbnic_dev *fbd,
+ struct fbnic_fw_completion *cmpl_data)
+{
+ unsigned long flags;
+ int err;
+
+ spin_lock_irqsave(&fbd->fw_tx_lock, flags);
+ err = fbnic_mbx_set_cmpl_slot(fbd, cmpl_data);
+ spin_unlock_irqrestore(&fbd->fw_tx_lock, flags);
+
+ return err;
+}
+
static int fbnic_mbx_map_req_w_cmpl(struct fbnic_dev *fbd,
struct fbnic_tlv_msg *msg,
struct fbnic_fw_completion *cmpl_data)
@@ -266,23 +317,20 @@ static int fbnic_mbx_map_req_w_cmpl(struct fbnic_dev *fbd,
int err;
spin_lock_irqsave(&fbd->fw_tx_lock, flags);
-
- /* If we are already waiting on a completion then abort */
- if (cmpl_data && fbd->cmpl_data) {
- err = -EBUSY;
- goto unlock_mbx;
+ if (cmpl_data) {
+ err = fbnic_mbx_set_cmpl_slot(fbd, cmpl_data);
+ if (err)
+ goto unlock_mbx;
}
- /* Record completion location and submit request */
- if (cmpl_data)
- fbd->cmpl_data = cmpl_data;
-
err = fbnic_mbx_map_msg(fbd, FBNIC_IPC_MBX_TX_IDX, msg,
le16_to_cpu(msg->hdr.len) * sizeof(u32), 1);
- /* If msg failed then clear completion data for next caller */
+ /* If we successfully reserved a completion and msg failed
+ * then clear completion data for next caller
+ */
if (err && cmpl_data)
- fbd->cmpl_data = NULL;
+ fbnic_mbx_clear_cmpl_slot(fbd, cmpl_data);
unlock_mbx:
spin_unlock_irqrestore(&fbd->fw_tx_lock, flags);
@@ -304,12 +352,18 @@ fbnic_fw_get_cmpl_by_type(struct fbnic_dev *fbd, u32 msg_type)
{
struct fbnic_fw_completion *cmpl_data = NULL;
unsigned long flags;
+ int i;
spin_lock_irqsave(&fbd->fw_tx_lock, flags);
- if (fbd->cmpl_data && fbd->cmpl_data->msg_type == msg_type) {
- cmpl_data = fbd->cmpl_data;
- kref_get(&fbd->cmpl_data->ref_count);
+ for (i = 0; i < FBNIC_MBX_CMPL_SLOTS; i++) {
+ if (fbd->cmpl_data[i] &&
+ fbd->cmpl_data[i]->msg_type == msg_type) {
+ cmpl_data = fbd->cmpl_data[i];
+ kref_get(&cmpl_data->ref_count);
+ break;
+ }
}
+
spin_unlock_irqrestore(&fbd->fw_tx_lock, flags);
return cmpl_data;
@@ -925,10 +979,16 @@ static void __fbnic_fw_evict_cmpl(struct fbnic_fw_completion *cmpl_data)
static void fbnic_mbx_evict_all_cmpl(struct fbnic_dev *fbd)
{
- if (fbd->cmpl_data) {
- __fbnic_fw_evict_cmpl(fbd->cmpl_data);
- fbd->cmpl_data = NULL;
+ int i;
+
+ for (i = 0; i < FBNIC_MBX_CMPL_SLOTS; i++) {
+ struct fbnic_fw_completion *cmpl_data = fbd->cmpl_data[i];
+
+ if (cmpl_data)
+ __fbnic_fw_evict_cmpl(cmpl_data);
}
+
+ memset(fbd->cmpl_data, 0, sizeof(fbd->cmpl_data));
}
void fbnic_mbx_flush_tx(struct fbnic_dev *fbd)
@@ -989,12 +1049,13 @@ void fbnic_fw_init_cmpl(struct fbnic_fw_completion *fw_cmpl,
kref_init(&fw_cmpl->ref_count);
}
-void fbnic_fw_clear_compl(struct fbnic_dev *fbd)
+void fbnic_fw_clear_cmpl(struct fbnic_dev *fbd,
+ struct fbnic_fw_completion *fw_cmpl)
{
unsigned long flags;
spin_lock_irqsave(&fbd->fw_tx_lock, flags);
- fbd->cmpl_data = NULL;
+ fbnic_mbx_clear_cmpl_slot(fbd, fw_cmpl);
spin_unlock_irqrestore(&fbd->fw_tx_lock, flags);
}
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_fw.h b/drivers/net/ethernet/meta/fbnic/fbnic_fw.h
index 692dfd8746e7..39dec0792090 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_fw.h
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_fw.h
@@ -60,6 +60,8 @@ struct fbnic_fw_completion {
void fbnic_mbx_init(struct fbnic_dev *fbd);
void fbnic_mbx_clean(struct fbnic_dev *fbd);
+int fbnic_mbx_set_cmpl(struct fbnic_dev *fbd,
+ struct fbnic_fw_completion *cmpl_data);
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);
@@ -70,7 +72,8 @@ int fbnic_fw_xmit_tsene_read_msg(struct fbnic_dev *fbd,
struct fbnic_fw_completion *cmpl_data);
void fbnic_fw_init_cmpl(struct fbnic_fw_completion *cmpl_data,
u32 msg_type);
-void fbnic_fw_clear_compl(struct fbnic_dev *fbd);
+void fbnic_fw_clear_cmpl(struct fbnic_dev *fbd,
+ struct fbnic_fw_completion *cmpl_data);
void fbnic_fw_put_cmpl(struct fbnic_fw_completion *cmpl_data);
#define fbnic_mk_full_fw_ver_str(_rev_id, _delim, _commit, _str, _str_sz) \
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_mac.c b/drivers/net/ethernet/meta/fbnic/fbnic_mac.c
index dde4a37116e2..4ba6f8d10775 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_mac.c
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_mac.c
@@ -744,7 +744,7 @@ static int fbnic_mac_get_sensor_asic(struct fbnic_dev *fbd, int id,
*val = *sensor;
exit_cleanup:
- fbnic_fw_clear_compl(fbd);
+ fbnic_fw_clear_cmpl(fbd, fw_cmpl);
exit_free:
fbnic_fw_put_cmpl(fw_cmpl);
--
2.47.1
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH net-next v5 4/5] eth: fbnic: Add mailbox support for PLDM updates
2025-05-12 18:53 [PATCH net-next v5 0/5] eth: fbnic: Add devlink dev flash support Lee Trager
` (2 preceding siblings ...)
2025-05-12 18:53 ` [PATCH net-next v5 3/5] eth: fbnic: Add support for multiple concurrent completion messages Lee Trager
@ 2025-05-12 18:54 ` Lee Trager
2025-05-12 18:54 ` [PATCH net-next v5 5/5] eth: fbnic: Add devlink dev flash support Lee Trager
2025-05-15 11:54 ` [PATCH net-next v5 0/5] " Paolo Abeni
5 siblings, 0 replies; 12+ messages in thread
From: Lee Trager @ 2025-05-12 18:54 UTC (permalink / raw)
To: Alexander Duyck, Jakub Kicinski, kernel-team, David S. Miller,
Eric Dumazet, Paolo Abeni, Simon Horman, Jonathan Corbet,
Andrew Lunn, Jacob Keller, Mohsin Bashir, Sanman Pradhan, Su Hui,
Lee Trager, Al Viro
Cc: Andrew Lunn, netdev, linux-doc, linux-kernel
Add three new mailbox messages to support PLDM upgrades:
* FW_START_UPGRADE - Enables driver to request starting a firmware upgrade
by specifying the component to be upgraded and its
size.
* WRITE_CHUNK - Allows firmware to request driver to send a chunk of
data at the specified offset.
* FINISH_UPGRADE - Allows firmware to cancel the upgrade process and
return an error.
Signed-off-by: Lee Trager <lee@trager.us>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Reviewed-by: Simon Horman <horms@kernel.org>
---
drivers/net/ethernet/meta/fbnic/fbnic_fw.c | 191 +++++++++++++++++++++
drivers/net/ethernet/meta/fbnic/fbnic_fw.h | 37 ++++
2 files changed, 228 insertions(+)
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_fw.c b/drivers/net/ethernet/meta/fbnic/fbnic_fw.c
index 6fcba4e8c21e..6a803a59dc25 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_fw.c
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_fw.c
@@ -766,6 +766,188 @@ void fbnic_fw_check_heartbeat(struct fbnic_dev *fbd)
dev_warn(fbd->dev, "Failed to send heartbeat message\n");
}
+int fbnic_fw_xmit_fw_start_upgrade(struct fbnic_dev *fbd,
+ struct fbnic_fw_completion *cmpl_data,
+ unsigned int id, unsigned int len)
+{
+ struct fbnic_tlv_msg *msg;
+ int err;
+
+ if (!fbnic_fw_present(fbd))
+ return -ENODEV;
+
+ if (!len)
+ return -EINVAL;
+
+ msg = fbnic_tlv_msg_alloc(FBNIC_TLV_MSG_ID_FW_START_UPGRADE_REQ);
+ if (!msg)
+ return -ENOMEM;
+
+ err = fbnic_tlv_attr_put_int(msg, FBNIC_FW_START_UPGRADE_SECTION, id);
+ if (err)
+ goto free_message;
+
+ err = fbnic_tlv_attr_put_int(msg, FBNIC_FW_START_UPGRADE_IMAGE_LENGTH,
+ len);
+ if (err)
+ goto free_message;
+
+ err = fbnic_mbx_map_req_w_cmpl(fbd, msg, cmpl_data);
+ if (err)
+ goto free_message;
+
+ return 0;
+
+free_message:
+ free_page((unsigned long)msg);
+ return err;
+}
+
+static const struct fbnic_tlv_index fbnic_fw_start_upgrade_resp_index[] = {
+ FBNIC_TLV_ATTR_S32(FBNIC_FW_START_UPGRADE_ERROR),
+ FBNIC_TLV_ATTR_LAST
+};
+
+static int fbnic_fw_parse_fw_start_upgrade_resp(void *opaque,
+ struct fbnic_tlv_msg **results)
+{
+ struct fbnic_fw_completion *cmpl_data;
+ struct fbnic_dev *fbd = opaque;
+ u32 msg_type;
+ s32 err;
+
+ /* Verify we have a completion pointer */
+ msg_type = FBNIC_TLV_MSG_ID_FW_START_UPGRADE_REQ;
+ cmpl_data = fbnic_fw_get_cmpl_by_type(fbd, msg_type);
+ if (!cmpl_data)
+ return -ENOSPC;
+
+ /* Check for errors */
+ err = fta_get_sint(results, FBNIC_FW_START_UPGRADE_ERROR);
+
+ cmpl_data->result = err;
+ complete(&cmpl_data->done);
+ fbnic_fw_put_cmpl(cmpl_data);
+
+ return 0;
+}
+
+int fbnic_fw_xmit_fw_write_chunk(struct fbnic_dev *fbd,
+ const u8 *data, u32 offset, u16 length,
+ int cancel_error)
+{
+ struct fbnic_tlv_msg *msg;
+ int err;
+
+ msg = fbnic_tlv_msg_alloc(FBNIC_TLV_MSG_ID_FW_WRITE_CHUNK_RESP);
+ if (!msg)
+ return -ENOMEM;
+
+ /* Report error to FW to cancel upgrade */
+ if (cancel_error) {
+ err = fbnic_tlv_attr_put_int(msg, FBNIC_FW_WRITE_CHUNK_ERROR,
+ cancel_error);
+ if (err)
+ goto free_message;
+ }
+
+ if (data) {
+ err = fbnic_tlv_attr_put_int(msg, FBNIC_FW_WRITE_CHUNK_OFFSET,
+ offset);
+ if (err)
+ goto free_message;
+
+ err = fbnic_tlv_attr_put_int(msg, FBNIC_FW_WRITE_CHUNK_LENGTH,
+ length);
+ if (err)
+ goto free_message;
+
+ err = fbnic_tlv_attr_put_value(msg, FBNIC_FW_WRITE_CHUNK_DATA,
+ data + offset, length);
+ if (err)
+ goto free_message;
+ }
+
+ err = fbnic_mbx_map_tlv_msg(fbd, msg);
+ if (err)
+ goto free_message;
+
+ return 0;
+
+free_message:
+ free_page((unsigned long)msg);
+ return err;
+}
+
+static const struct fbnic_tlv_index fbnic_fw_write_chunk_req_index[] = {
+ FBNIC_TLV_ATTR_U32(FBNIC_FW_WRITE_CHUNK_OFFSET),
+ FBNIC_TLV_ATTR_U32(FBNIC_FW_WRITE_CHUNK_LENGTH),
+ FBNIC_TLV_ATTR_LAST
+};
+
+static int fbnic_fw_parse_fw_write_chunk_req(void *opaque,
+ struct fbnic_tlv_msg **results)
+{
+ struct fbnic_fw_completion *cmpl_data;
+ struct fbnic_dev *fbd = opaque;
+ u32 msg_type;
+ u32 offset;
+ u32 length;
+
+ /* Verify we have a completion pointer */
+ msg_type = FBNIC_TLV_MSG_ID_FW_WRITE_CHUNK_REQ;
+ cmpl_data = fbnic_fw_get_cmpl_by_type(fbd, msg_type);
+ if (!cmpl_data)
+ return -ENOSPC;
+
+ /* Pull length/offset pair and mark it as complete */
+ offset = fta_get_uint(results, FBNIC_FW_WRITE_CHUNK_OFFSET);
+ length = fta_get_uint(results, FBNIC_FW_WRITE_CHUNK_LENGTH);
+ cmpl_data->u.fw_update.offset = offset;
+ cmpl_data->u.fw_update.length = length;
+
+ complete(&cmpl_data->done);
+ fbnic_fw_put_cmpl(cmpl_data);
+
+ return 0;
+}
+
+static const struct fbnic_tlv_index fbnic_fw_finish_upgrade_req_index[] = {
+ FBNIC_TLV_ATTR_S32(FBNIC_FW_FINISH_UPGRADE_ERROR),
+ FBNIC_TLV_ATTR_LAST
+};
+
+static int fbnic_fw_parse_fw_finish_upgrade_req(void *opaque,
+ struct fbnic_tlv_msg **results)
+{
+ struct fbnic_fw_completion *cmpl_data;
+ struct fbnic_dev *fbd = opaque;
+ u32 msg_type;
+ s32 err;
+
+ /* Verify we have a completion pointer */
+ msg_type = FBNIC_TLV_MSG_ID_FW_WRITE_CHUNK_REQ;
+ cmpl_data = fbnic_fw_get_cmpl_by_type(fbd, msg_type);
+ if (!cmpl_data)
+ return -ENOSPC;
+
+ /* Check for errors */
+ err = fta_get_sint(results, FBNIC_FW_FINISH_UPGRADE_ERROR);
+
+ /* Close out update by incrementing offset by length which should
+ * match the total size of the component. Set length to 0 since no
+ * new chunks will be requested.
+ */
+ cmpl_data->u.fw_update.offset += cmpl_data->u.fw_update.length;
+ cmpl_data->u.fw_update.length = 0;
+
+ cmpl_data->result = err;
+ complete(&cmpl_data->done);
+ fbnic_fw_put_cmpl(cmpl_data);
+
+ return 0;
+}
+
/**
* fbnic_fw_xmit_tsene_read_msg - Create and transmit a sensor read request
* @fbd: FBNIC device structure
@@ -850,6 +1032,15 @@ static const struct fbnic_tlv_parser fbnic_fw_tlv_parser[] = {
fbnic_fw_parse_ownership_resp),
FBNIC_TLV_PARSER(HEARTBEAT_RESP, fbnic_heartbeat_resp_index,
fbnic_fw_parse_heartbeat_resp),
+ FBNIC_TLV_PARSER(FW_START_UPGRADE_RESP,
+ fbnic_fw_start_upgrade_resp_index,
+ fbnic_fw_parse_fw_start_upgrade_resp),
+ FBNIC_TLV_PARSER(FW_WRITE_CHUNK_REQ,
+ fbnic_fw_write_chunk_req_index,
+ fbnic_fw_parse_fw_write_chunk_req),
+ FBNIC_TLV_PARSER(FW_FINISH_UPGRADE_REQ,
+ fbnic_fw_finish_upgrade_req_index,
+ fbnic_fw_parse_fw_finish_upgrade_req),
FBNIC_TLV_PARSER(TSENE_READ_RESP,
fbnic_tsene_read_resp_index,
fbnic_fw_parse_tsene_read_resp),
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_fw.h b/drivers/net/ethernet/meta/fbnic/fbnic_fw.h
index 39dec0792090..0ab6ae3859e4 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_fw.h
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_fw.h
@@ -51,6 +51,10 @@ struct fbnic_fw_completion {
struct kref ref_count;
int result;
union {
+ struct {
+ u32 offset;
+ u32 length;
+ } fw_update;
struct {
s32 millivolts;
s32 millidegrees;
@@ -68,6 +72,12 @@ void fbnic_mbx_flush_tx(struct fbnic_dev *fbd);
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);
+int fbnic_fw_xmit_fw_start_upgrade(struct fbnic_dev *fbd,
+ struct fbnic_fw_completion *cmpl_data,
+ unsigned int id, unsigned int len);
+int fbnic_fw_xmit_fw_write_chunk(struct fbnic_dev *fbd,
+ const u8 *data, u32 offset, u16 length,
+ int cancel_error);
int fbnic_fw_xmit_tsene_read_msg(struct fbnic_dev *fbd,
struct fbnic_fw_completion *cmpl_data);
void fbnic_fw_init_cmpl(struct fbnic_fw_completion *cmpl_data,
@@ -99,6 +109,12 @@ enum {
FBNIC_TLV_MSG_ID_OWNERSHIP_RESP = 0x13,
FBNIC_TLV_MSG_ID_HEARTBEAT_REQ = 0x14,
FBNIC_TLV_MSG_ID_HEARTBEAT_RESP = 0x15,
+ FBNIC_TLV_MSG_ID_FW_START_UPGRADE_REQ = 0x22,
+ FBNIC_TLV_MSG_ID_FW_START_UPGRADE_RESP = 0x23,
+ FBNIC_TLV_MSG_ID_FW_WRITE_CHUNK_REQ = 0x24,
+ FBNIC_TLV_MSG_ID_FW_WRITE_CHUNK_RESP = 0x25,
+ FBNIC_TLV_MSG_ID_FW_FINISH_UPGRADE_REQ = 0x28,
+ FBNIC_TLV_MSG_ID_FW_FINISH_UPGRADE_RESP = 0x29,
FBNIC_TLV_MSG_ID_TSENE_READ_REQ = 0x3C,
FBNIC_TLV_MSG_ID_TSENE_READ_RESP = 0x3D,
};
@@ -154,4 +170,25 @@ enum {
FBNIC_FW_OWNERSHIP_FLAG = 0x0,
FBNIC_FW_OWNERSHIP_MSG_MAX
};
+
+enum {
+ FBNIC_FW_START_UPGRADE_ERROR = 0x0,
+ FBNIC_FW_START_UPGRADE_SECTION = 0x1,
+ FBNIC_FW_START_UPGRADE_IMAGE_LENGTH = 0x2,
+ FBNIC_FW_START_UPGRADE_MSG_MAX
+};
+
+enum {
+ FBNIC_FW_WRITE_CHUNK_OFFSET = 0x0,
+ FBNIC_FW_WRITE_CHUNK_LENGTH = 0x1,
+ FBNIC_FW_WRITE_CHUNK_DATA = 0x2,
+ FBNIC_FW_WRITE_CHUNK_ERROR = 0x3,
+ FBNIC_FW_WRITE_CHUNK_MSG_MAX
+};
+
+enum {
+ FBNIC_FW_FINISH_UPGRADE_ERROR = 0x0,
+ FBNIC_FW_FINISH_UPGRADE_MSG_MAX
+};
+
#endif /* _FBNIC_FW_H_ */
--
2.47.1
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH net-next v5 5/5] eth: fbnic: Add devlink dev flash support
2025-05-12 18:53 [PATCH net-next v5 0/5] eth: fbnic: Add devlink dev flash support Lee Trager
` (3 preceding siblings ...)
2025-05-12 18:54 ` [PATCH net-next v5 4/5] eth: fbnic: Add mailbox support for PLDM updates Lee Trager
@ 2025-05-12 18:54 ` Lee Trager
2025-05-12 19:13 ` Jacob Keller
` (2 more replies)
2025-05-15 11:54 ` [PATCH net-next v5 0/5] " Paolo Abeni
5 siblings, 3 replies; 12+ messages in thread
From: Lee Trager @ 2025-05-12 18:54 UTC (permalink / raw)
To: Alexander Duyck, Jakub Kicinski, kernel-team, David S. Miller,
Eric Dumazet, Paolo Abeni, Simon Horman, Jonathan Corbet,
Andrew Lunn, Jacob Keller, Mohsin Bashir, Sanman Pradhan, Su Hui,
Lee Trager, Al Viro
Cc: Andrew Lunn, netdev, linux-doc, linux-kernel
Add support to update the CMRT and control firmware as well as the UEFI
driver on fbnic using devlink dev flash.
Make sure the shutdown / quiescence paths like suspend take the devlink
lock to prevent them from interrupting the FW flashing process.
Signed-off-by: Lee Trager <lee@trager.us>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
V5:
* Make sure fbnic_pldm_match_record() always returns a bool
.../device_drivers/ethernet/meta/fbnic.rst | 11 +
drivers/net/ethernet/meta/Kconfig | 1 +
.../net/ethernet/meta/fbnic/fbnic_devlink.c | 260 +++++++++++++++++-
drivers/net/ethernet/meta/fbnic/fbnic_fw.h | 9 +
drivers/net/ethernet/meta/fbnic/fbnic_pci.c | 9 +
5 files changed, 289 insertions(+), 1 deletion(-)
diff --git a/Documentation/networking/device_drivers/ethernet/meta/fbnic.rst b/Documentation/networking/device_drivers/ethernet/meta/fbnic.rst
index 3483e498c08e..f8592dec8851 100644
--- a/Documentation/networking/device_drivers/ethernet/meta/fbnic.rst
+++ b/Documentation/networking/device_drivers/ethernet/meta/fbnic.rst
@@ -28,6 +28,17 @@ devlink dev info provides version information for all three components. In
addition to the version the hg commit hash of the build is included as a
separate entry.
+Upgrading Firmware
+------------------
+
+fbnic supports updating firmware using signed PLDM images with devlink dev
+flash. PLDM images are written into the flash. Flashing does not interrupt
+the operation of the device.
+
+On host boot the latest UEFI driver is always used, no explicit activation
+is required. Firmware activation is required to run new control firmware. cmrt
+firmware can only be activated by power cycling the NIC.
+
Statistics
----------
diff --git a/drivers/net/ethernet/meta/Kconfig b/drivers/net/ethernet/meta/Kconfig
index 831921b9d4d5..3ba527514f1e 100644
--- a/drivers/net/ethernet/meta/Kconfig
+++ b/drivers/net/ethernet/meta/Kconfig
@@ -27,6 +27,7 @@ config FBNIC
select NET_DEVLINK
select PAGE_POOL
select PHYLINK
+ select PLDMFW
help
This driver supports Meta Platforms Host Network Interface.
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_devlink.c b/drivers/net/ethernet/meta/fbnic/fbnic_devlink.c
index 0072d612215e..71d9461a0d1b 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_devlink.c
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_devlink.c
@@ -3,10 +3,12 @@
#include <linux/unaligned.h>
#include <linux/pci.h>
+#include <linux/pldmfw.h>
#include <linux/types.h>
#include <net/devlink.h>
#include "fbnic.h"
+#include "fbnic_tlv.h"
#define FBNIC_SN_STR_LEN 24
@@ -109,8 +111,264 @@ static int fbnic_devlink_info_get(struct devlink *devlink,
return 0;
}
+static bool
+fbnic_pldm_match_record(struct pldmfw *context, struct pldmfw_record *record)
+{
+ struct pldmfw_desc_tlv *desc;
+ u32 anti_rollback_ver = 0;
+ struct devlink *devlink;
+ struct fbnic_dev *fbd;
+ struct pci_dev *pdev;
+
+ /* First, use the standard PCI matching function */
+ if (!pldmfw_op_pci_match_record(context, record))
+ return false;
+
+ pdev = to_pci_dev(context->dev);
+ fbd = pci_get_drvdata(pdev);
+ devlink = priv_to_devlink(fbd);
+
+ /* If PCI match is successful, check for vendor-specific descriptors */
+ list_for_each_entry(desc, &record->descs, entry) {
+ if (desc->type != PLDM_DESC_ID_VENDOR_DEFINED)
+ continue;
+
+ if (desc->size < 21 || desc->data[0] != 1 ||
+ desc->data[1] != 15)
+ continue;
+
+ if (memcmp(desc->data + 2, "AntiRollbackVer", 15) != 0)
+ continue;
+
+ anti_rollback_ver = get_unaligned_le32(desc->data + 17);
+ break;
+ }
+
+ /* Compare versions and return error if they do not match */
+ if (anti_rollback_ver < fbd->fw_cap.anti_rollback_version) {
+ char buf[128];
+
+ snprintf(buf, sizeof(buf),
+ "New firmware anti-rollback version (0x%x) is older than device version (0x%x)!",
+ anti_rollback_ver, fbd->fw_cap.anti_rollback_version);
+ devlink_flash_update_status_notify(devlink, buf,
+ "Anti-Rollback", 0, 0);
+
+ return false;
+ }
+
+ return true;
+}
+
+static int
+fbnic_flash_start(struct fbnic_dev *fbd, struct pldmfw_component *component)
+{
+ struct fbnic_fw_completion *cmpl;
+ int err;
+
+ cmpl = kzalloc(sizeof(*cmpl), GFP_KERNEL);
+ if (!cmpl)
+ return -ENOMEM;
+
+ fbnic_fw_init_cmpl(cmpl, FBNIC_TLV_MSG_ID_FW_START_UPGRADE_REQ);
+ err = fbnic_fw_xmit_fw_start_upgrade(fbd, cmpl,
+ component->identifier,
+ component->component_size);
+ if (err)
+ goto cmpl_free;
+
+ /* Wait for firmware to ack firmware upgrade start */
+ if (wait_for_completion_timeout(&cmpl->done, 10 * HZ))
+ err = cmpl->result;
+ else
+ err = -ETIMEDOUT;
+
+ fbnic_fw_clear_cmpl(fbd, cmpl);
+cmpl_free:
+ fbnic_fw_put_cmpl(cmpl);
+
+ return err;
+}
+
+static int
+fbnic_flash_component(struct pldmfw *context,
+ struct pldmfw_component *component)
+{
+ const u8 *data = component->component_data;
+ const u32 size = component->component_size;
+ struct fbnic_fw_completion *cmpl;
+ const char *component_name;
+ struct devlink *devlink;
+ struct fbnic_dev *fbd;
+ struct pci_dev *pdev;
+ u32 offset = 0;
+ u32 length = 0;
+ char buf[32];
+ int err;
+
+ pdev = to_pci_dev(context->dev);
+ fbd = pci_get_drvdata(pdev);
+ devlink = priv_to_devlink(fbd);
+
+ switch (component->identifier) {
+ case QSPI_SECTION_CMRT:
+ component_name = "boot1";
+ break;
+ case QSPI_SECTION_CONTROL_FW:
+ component_name = "boot2";
+ break;
+ case QSPI_SECTION_OPTION_ROM:
+ component_name = "option-rom";
+ break;
+ default:
+ snprintf(buf, sizeof(buf), "Unknown component ID %u!",
+ component->identifier);
+ devlink_flash_update_status_notify(devlink, buf, NULL, 0,
+ size);
+ return -EINVAL;
+ }
+
+ /* Once firmware receives the request to start upgrading it responds
+ * with two messages:
+ * 1. An ACK that it received the message and possible error code
+ * indicating that an upgrade is not currently possible.
+ * 2. A request for the first chunk of data
+ *
+ * Setup completions for write before issuing the start message so
+ * the driver can catch both messages.
+ */
+ cmpl = kzalloc(sizeof(*cmpl), GFP_KERNEL);
+ if (!cmpl)
+ return -ENOMEM;
+
+ fbnic_fw_init_cmpl(cmpl, FBNIC_TLV_MSG_ID_FW_WRITE_CHUNK_REQ);
+ err = fbnic_mbx_set_cmpl(fbd, cmpl);
+ if (err)
+ goto cmpl_free;
+
+ devlink_flash_update_timeout_notify(devlink, "Initializing",
+ component_name, 15);
+ err = fbnic_flash_start(fbd, component);
+ if (err)
+ goto err_no_msg;
+
+ while (offset < size) {
+ if (!wait_for_completion_timeout(&cmpl->done, 15 * HZ)) {
+ err = -ETIMEDOUT;
+ break;
+ }
+
+ err = cmpl->result;
+ if (err)
+ break;
+
+ /* Verify firmware is requesting the next chunk in the seq. */
+ if (cmpl->u.fw_update.offset != offset + length) {
+ err = -EFAULT;
+ break;
+ }
+
+ offset = cmpl->u.fw_update.offset;
+ length = cmpl->u.fw_update.length;
+
+ if (length > TLV_MAX_DATA || offset + length > size) {
+ err = -EFAULT;
+ break;
+ }
+
+ devlink_flash_update_status_notify(devlink, "Flashing",
+ component_name,
+ offset, size);
+
+ /* Mailbox will set length to 0 once it receives the finish
+ * message.
+ */
+ if (!length)
+ continue;
+
+ reinit_completion(&cmpl->done);
+ err = fbnic_fw_xmit_fw_write_chunk(fbd, data, offset, length,
+ 0);
+ if (err)
+ break;
+ }
+
+ if (err) {
+ fbnic_fw_xmit_fw_write_chunk(fbd, NULL, 0, 0, err);
+err_no_msg:
+ snprintf(buf, sizeof(buf), "Mailbox encountered error %d!",
+ err);
+ devlink_flash_update_status_notify(devlink, buf,
+ component_name, 0, 0);
+ }
+
+ fbnic_fw_clear_cmpl(fbd, cmpl);
+cmpl_free:
+ fbnic_fw_put_cmpl(cmpl);
+
+ return err;
+}
+
+static const struct pldmfw_ops fbnic_pldmfw_ops = {
+ .match_record = fbnic_pldm_match_record,
+ .flash_component = fbnic_flash_component,
+};
+
+static int
+fbnic_devlink_flash_update(struct devlink *devlink,
+ struct devlink_flash_update_params *params,
+ struct netlink_ext_ack *extack)
+{
+ struct fbnic_dev *fbd = devlink_priv(devlink);
+ const struct firmware *fw = params->fw;
+ struct device *dev = fbd->dev;
+ struct pldmfw context;
+ char *err_msg;
+ int err;
+
+ context.ops = &fbnic_pldmfw_ops;
+ context.dev = dev;
+
+ err = pldmfw_flash_image(&context, fw);
+ if (err) {
+ switch (err) {
+ case -EINVAL:
+ err_msg = "Invalid image";
+ break;
+ case -EOPNOTSUPP:
+ err_msg = "Unsupported image";
+ break;
+ case -ENOMEM:
+ err_msg = "Out of memory";
+ break;
+ case -EFAULT:
+ err_msg = "Invalid header";
+ break;
+ case -ENOENT:
+ err_msg = "No matching record";
+ break;
+ case -ENODEV:
+ err_msg = "No matching device";
+ break;
+ case -ETIMEDOUT:
+ err_msg = "Timed out waiting for reply";
+ break;
+ default:
+ err_msg = "Unknown error";
+ break;
+ }
+
+ NL_SET_ERR_MSG_FMT_MOD(extack,
+ "Failed to flash PLDM Image: %s (error: %d)",
+ err_msg, err);
+ }
+
+ return err;
+}
+
static const struct devlink_ops fbnic_devlink_ops = {
- .info_get = fbnic_devlink_info_get,
+ .info_get = fbnic_devlink_info_get,
+ .flash_update = fbnic_devlink_flash_update,
};
void fbnic_devlink_free(struct fbnic_dev *fbd)
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_fw.h b/drivers/net/ethernet/meta/fbnic/fbnic_fw.h
index 0ab6ae3859e4..6baac10fd688 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_fw.h
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_fw.h
@@ -100,6 +100,15 @@ do { \
#define fbnic_mk_fw_ver_str(_rev_id, _str) \
fbnic_mk_full_fw_ver_str(_rev_id, "", "", _str, sizeof(_str))
+enum {
+ QSPI_SECTION_CMRT = 0,
+ QSPI_SECTION_CONTROL_FW = 1,
+ QSPI_SECTION_UCODE = 2,
+ QSPI_SECTION_OPTION_ROM = 3,
+ QSPI_SECTION_USER = 4,
+ QSPI_SECTION_INVALID,
+};
+
#define FW_HEARTBEAT_PERIOD (10 * HZ)
enum {
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_pci.c b/drivers/net/ethernet/meta/fbnic/fbnic_pci.c
index 70a852b3e99d..249d3ef862d5 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_pci.c
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_pci.c
@@ -6,6 +6,7 @@
#include <linux/pci.h>
#include <linux/rtnetlink.h>
#include <linux/types.h>
+#include <net/devlink.h>
#include "fbnic.h"
#include "fbnic_drvinfo.h"
@@ -388,8 +389,12 @@ static int fbnic_pm_suspend(struct device *dev)
rtnl_unlock();
null_uc_addr:
+ devl_lock(priv_to_devlink(fbd));
+
fbnic_fw_free_mbx(fbd);
+ devl_unlock(priv_to_devlink(fbd));
+
/* Free the IRQs so they aren't trying to occupy sleeping CPUs */
fbnic_free_irqs(fbd);
@@ -420,11 +425,15 @@ static int __fbnic_pm_resume(struct device *dev)
fbd->mac->init_regs(fbd);
+ devl_lock(priv_to_devlink(fbd));
+
/* Re-enable mailbox */
err = fbnic_fw_request_mbx(fbd);
if (err)
goto err_free_irqs;
+ devl_unlock(priv_to_devlink(fbd));
+
/* No netdev means there isn't a network interface to bring up */
if (fbnic_init_failure(fbd))
return 0;
--
2.47.1
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH net-next v5 1/5] pldmfw: Don't require send_package_data or send_component_table to be defined
2025-05-12 18:53 ` [PATCH net-next v5 1/5] pldmfw: Don't require send_package_data or send_component_table to be defined Lee Trager
@ 2025-05-12 19:08 ` Jacob Keller
0 siblings, 0 replies; 12+ messages in thread
From: Jacob Keller @ 2025-05-12 19:08 UTC (permalink / raw)
To: Lee Trager, Alexander Duyck, Jakub Kicinski, kernel-team,
David S. Miller, Eric Dumazet, Paolo Abeni, Simon Horman,
Jonathan Corbet, Andrew Lunn, Mohsin Bashir, Sanman Pradhan,
Su Hui, Al Viro
Cc: Andrew Lunn, netdev, linux-doc, linux-kernel
On 5/12/2025 11:53 AM, Lee Trager wrote:
> Not all drivers require send_package_data or send_component_table when
> updating firmware. Instead of forcing drivers to implement a stub allow
> these functions to go undefined.
>
> Signed-off-by: Lee Trager <lee@trager.us>
> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
> Reviewed-by: Simon Horman <horms@kernel.org>
> ---
I guess we crossed airwaves when I sent my tags to v4 :)
Acked-by: Jacob Keller <jacob.e.keller@intel.com>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH net-next v5 3/5] eth: fbnic: Add support for multiple concurrent completion messages
2025-05-12 18:53 ` [PATCH net-next v5 3/5] eth: fbnic: Add support for multiple concurrent completion messages Lee Trager
@ 2025-05-12 19:08 ` Jacob Keller
0 siblings, 0 replies; 12+ messages in thread
From: Jacob Keller @ 2025-05-12 19:08 UTC (permalink / raw)
To: Lee Trager, Alexander Duyck, Jakub Kicinski, kernel-team,
David S. Miller, Eric Dumazet, Paolo Abeni, Simon Horman,
Jonathan Corbet, Andrew Lunn, Mohsin Bashir, Sanman Pradhan,
Su Hui, Al Viro
Cc: Andrew Lunn, netdev, linux-doc, linux-kernel
On 5/12/2025 11:53 AM, Lee Trager wrote:
> Extend fbnic mailbox to support multiple concurrent completion messages at
> once. This enables fbnic to support running multiple operations at once
> which depend on a response from firmware via the mailbox.
>
> Signed-off-by: Lee Trager <lee@trager.us>
> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
> Reviewed-by: Simon Horman <horms@kernel.org>
> ---
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH net-next v5 5/5] eth: fbnic: Add devlink dev flash support
2025-05-12 18:54 ` [PATCH net-next v5 5/5] eth: fbnic: Add devlink dev flash support Lee Trager
@ 2025-05-12 19:13 ` Jacob Keller
2025-05-13 13:45 ` Simon Horman
2025-05-15 10:58 ` Paolo Abeni
2 siblings, 0 replies; 12+ messages in thread
From: Jacob Keller @ 2025-05-12 19:13 UTC (permalink / raw)
To: Lee Trager, Alexander Duyck, Jakub Kicinski, kernel-team,
David S. Miller, Eric Dumazet, Paolo Abeni, Simon Horman,
Jonathan Corbet, Andrew Lunn, Mohsin Bashir, Sanman Pradhan,
Su Hui, Al Viro
Cc: Andrew Lunn, netdev, linux-doc, linux-kernel
On 5/12/2025 11:54 AM, Lee Trager wrote:
> Add support to update the CMRT and control firmware as well as the UEFI
> driver on fbnic using devlink dev flash.
>
> Make sure the shutdown / quiescence paths like suspend take the devlink
> lock to prevent them from interrupting the FW flashing process.
>
> Signed-off-by: Lee Trager <lee@trager.us>
> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
> ---
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH net-next v5 5/5] eth: fbnic: Add devlink dev flash support
2025-05-12 18:54 ` [PATCH net-next v5 5/5] eth: fbnic: Add devlink dev flash support Lee Trager
2025-05-12 19:13 ` Jacob Keller
@ 2025-05-13 13:45 ` Simon Horman
2025-05-15 10:58 ` Paolo Abeni
2 siblings, 0 replies; 12+ messages in thread
From: Simon Horman @ 2025-05-13 13:45 UTC (permalink / raw)
To: Lee Trager
Cc: Alexander Duyck, Jakub Kicinski, kernel-team, David S. Miller,
Eric Dumazet, Paolo Abeni, Jonathan Corbet, Andrew Lunn,
Jacob Keller, Mohsin Bashir, Sanman Pradhan, Su Hui, Al Viro,
Andrew Lunn, netdev, linux-doc, linux-kernel
On Mon, May 12, 2025 at 11:54:01AM -0700, Lee Trager wrote:
> Add support to update the CMRT and control firmware as well as the UEFI
> driver on fbnic using devlink dev flash.
>
> Make sure the shutdown / quiescence paths like suspend take the devlink
> lock to prevent them from interrupting the FW flashing process.
>
> Signed-off-by: Lee Trager <lee@trager.us>
> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
> ---
> V5:
> * Make sure fbnic_pldm_match_record() always returns a bool
Thanks for the update.
Reviewed-by: Simon Horman <horms@kernel.org>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH net-next v5 5/5] eth: fbnic: Add devlink dev flash support
2025-05-12 18:54 ` [PATCH net-next v5 5/5] eth: fbnic: Add devlink dev flash support Lee Trager
2025-05-12 19:13 ` Jacob Keller
2025-05-13 13:45 ` Simon Horman
@ 2025-05-15 10:58 ` Paolo Abeni
2 siblings, 0 replies; 12+ messages in thread
From: Paolo Abeni @ 2025-05-15 10:58 UTC (permalink / raw)
To: Lee Trager, Alexander Duyck, Jakub Kicinski, kernel-team,
David S. Miller, Eric Dumazet, Simon Horman, Jonathan Corbet,
Andrew Lunn, Jacob Keller, Mohsin Bashir, Sanman Pradhan, Su Hui,
Al Viro
Cc: Andrew Lunn, netdev, linux-doc, linux-kernel
On 5/12/25 8:54 PM, Lee Trager wrote:
> +static int
> +fbnic_flash_start(struct fbnic_dev *fbd, struct pldmfw_component *component)
> +{
> + struct fbnic_fw_completion *cmpl;
> + int err;
> +
> + cmpl = kzalloc(sizeof(*cmpl), GFP_KERNEL);
> + if (!cmpl)
> + return -ENOMEM;
> +
> + fbnic_fw_init_cmpl(cmpl, FBNIC_TLV_MSG_ID_FW_START_UPGRADE_REQ);
Minor note for a possible follow-up: since completion allocation is
always followed by fbnic_fw_init_cmpl(), you could boundle the 2 in some
helper.
No need to repost for this.
/P
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH net-next v5 0/5] eth: fbnic: Add devlink dev flash support
2025-05-12 18:53 [PATCH net-next v5 0/5] eth: fbnic: Add devlink dev flash support Lee Trager
` (4 preceding siblings ...)
2025-05-12 18:54 ` [PATCH net-next v5 5/5] eth: fbnic: Add devlink dev flash support Lee Trager
@ 2025-05-15 11:54 ` Paolo Abeni
5 siblings, 0 replies; 12+ messages in thread
From: Paolo Abeni @ 2025-05-15 11:54 UTC (permalink / raw)
To: Lee Trager, Alexander Duyck, Jakub Kicinski, kernel-team,
David S. Miller, Eric Dumazet, Simon Horman, Jonathan Corbet,
Andrew Lunn, Jacob Keller, Mohsin Bashir, Sanman Pradhan, Su Hui,
Al Viro
Cc: Andrew Lunn, netdev, linux-doc, linux-kernel
On 5/12/25 8:53 PM, Lee Trager wrote:
> fbnic supports updating firmware using signed PLDM images. PLDM images are
> written into the flash. Flashing does not interrupt the operation of the
> device.
Apparently the bot did not notice, but I applied the series a little
time ago, thanks!
Paolo
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2025-05-15 11:54 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-05-12 18:53 [PATCH net-next v5 0/5] eth: fbnic: Add devlink dev flash support Lee Trager
2025-05-12 18:53 ` [PATCH net-next v5 1/5] pldmfw: Don't require send_package_data or send_component_table to be defined Lee Trager
2025-05-12 19:08 ` Jacob Keller
2025-05-12 18:53 ` [PATCH net-next v5 2/5] eth: fbnic: Accept minimum anti-rollback version from firmware Lee Trager
2025-05-12 18:53 ` [PATCH net-next v5 3/5] eth: fbnic: Add support for multiple concurrent completion messages Lee Trager
2025-05-12 19:08 ` Jacob Keller
2025-05-12 18:54 ` [PATCH net-next v5 4/5] eth: fbnic: Add mailbox support for PLDM updates Lee Trager
2025-05-12 18:54 ` [PATCH net-next v5 5/5] eth: fbnic: Add devlink dev flash support Lee Trager
2025-05-12 19:13 ` Jacob Keller
2025-05-13 13:45 ` Simon Horman
2025-05-15 10:58 ` Paolo Abeni
2025-05-15 11:54 ` [PATCH net-next v5 0/5] " Paolo Abeni
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).