[net-next PATCH 1/2] fbnic: Don't reject capabilities when BMC is present without a MAC
From: Alexander Duyck <hidden>
Date: 2026-09-03 17:58:01
Subsystem:
meta ethernet drivers, networking drivers, the rest · Maintainers:
Alexander Duyck, Jakub Kicinski, Andrew Lunn, "David S. Miller", Eric Dumazet, Paolo Abeni, Linus Torvalds
From: Alexander Duyck <alexanderduyck@fb.com> fbnic_fw_parse_cap_resp() returns -EINVAL when the firmware reports the BMC present but includes no BMC MAC address array. The firmware reports the BMC present as soon as its NC-SI channel is enabled, which happens before the BMC has been assigned a MAC address; during that window the message legitimately carries no MAC array. The firmware and link fields are parsed earlier in the function so they are retained, but returning -EINVAL abandons the rest of the response: the BMC presence state, the all-multi flag and the anti-rollback version are never recorded, and need_bmc_tcam_reinit is left unset so the BMC TCAM is not refreshed. The parser also reports the whole capabilities message as malformed even though it is well formed. Treat a present BMC with no MAC array as the BMC not being present: clear the stored BMC MAC addresses and continue parsing the remainder of the message. Factor the BMC capability handling out into fbnic_fw_parse_bmc_cap() while here. Signed-off-by: Alexander Duyck <alexanderduyck@fb.com> --- drivers/net/ethernet/meta/fbnic/fbnic_fw.c | 56 +++++++++++++++++++--------- 1 file changed, 37 insertions(+), 19 deletions(-)
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_fw.c b/drivers/net/ethernet/meta/fbnic/fbnic_fw.c
index ff1674eff7ad..bf8006710f46 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_fw.c
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_fw.c@@ -607,6 +607,40 @@ static int fbnic_fw_parse_bmc_addrs(u8 bmc_mac_addr[][ETH_ALEN], return 0; } +static int fbnic_fw_parse_bmc_cap(struct fbnic_dev *fbd, + struct fbnic_tlv_msg **results, + bool *bmc_present, u32 *all_multi) +{ + struct fbnic_tlv_msg *attr; + int err; + + /* The FW reports the BMC present as soon as its NC-SI channel is + * enabled, which is before the BMC has been assigned a MAC address. + * In that window the message carries no MAC array; there is nothing + * to program, so treat the BMC as absent. On any absence clear the + * stored BMC MAC addresses and report the BMC as not present. + */ + if (!results[FBNIC_FW_CAP_RESP_BMC_PRESENT]) + goto no_bmc; + + attr = results[FBNIC_FW_CAP_RESP_BMC_MAC_ARRAY]; + if (!attr) + goto no_bmc; + + err = fbnic_fw_parse_bmc_addrs(fbd->fw_cap.bmc_mac_addr, attr, 4); + if (err) + return err; + + *all_multi = fta_get_uint(results, FBNIC_FW_CAP_RESP_BMC_ALL_MULTI); + *bmc_present = true; + return 0; + +no_bmc: + memset(fbd->fw_cap.bmc_mac_addr, 0, sizeof(fbd->fw_cap.bmc_mac_addr)); + *bmc_present = false; + return 0; +} + static int fbnic_fw_parse_cap_resp(void *opaque, struct fbnic_tlv_msg **results) { u32 all_multi = 0, version = 0;
@@ -671,25 +705,9 @@ static int fbnic_fw_parse_cap_resp(void *opaque, struct fbnic_tlv_msg **results) fbd->fw_cap.link_fec = fta_get_uint(results, FBNIC_FW_CAP_RESP_FW_LINK_FEC); - bmc_present = !!results[FBNIC_FW_CAP_RESP_BMC_PRESENT]; - if (bmc_present) { - struct fbnic_tlv_msg *attr; - - attr = results[FBNIC_FW_CAP_RESP_BMC_MAC_ARRAY]; - if (!attr) - return -EINVAL; - - err = fbnic_fw_parse_bmc_addrs(fbd->fw_cap.bmc_mac_addr, - attr, 4); - if (err) - return err; - - all_multi = - fta_get_uint(results, FBNIC_FW_CAP_RESP_BMC_ALL_MULTI); - } else { - memset(fbd->fw_cap.bmc_mac_addr, 0, - sizeof(fbd->fw_cap.bmc_mac_addr)); - } + err = fbnic_fw_parse_bmc_cap(fbd, results, &bmc_present, &all_multi); + if (err) + return err; fbd->fw_cap.bmc_present = bmc_present;