From 04a230b27d8f3e2312a6c6d07903bad6d09d133f Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Tue, 26 Aug 2025 12:45:01 -0700 Subject: [PATCH] fbnic: Add logic to repopulate RPC TCAM if BMC enables channel The BMC itself can decide to abandon a link and move onto another link in the event of things such as a link flap. As a result the driver may load with the BMC not present, and then needs to update things to support the BMC being present while the link is up and the NIC is passing traffic. To support this we add support to the watchdog to reinitialize the RPC to support adding the BMC unicast, multicast, and multicast promiscuous filters while the link is up and the NIC owns the link. Signed-off-by: Alexander Duyck Reviewed-by: Simon Horman Link: https://patch.msgid.link/175623750101.2246365.8518307324797058580.stgit@ahduyck-xeon-server.home.arpa Signed-off-by: Paolo Abeni --- drivers/net/ethernet/meta/fbnic/fbnic_fw.c | 3 +++ drivers/net/ethernet/meta/fbnic/fbnic_fw.h | 5 +++-- drivers/net/ethernet/meta/fbnic/fbnic_pci.c | 2 ++ drivers/net/ethernet/meta/fbnic/fbnic_rpc.c | 19 ++++++++++++------- drivers/net/ethernet/meta/fbnic/fbnic_rpc.h | 1 + 5 files changed, 21 insertions(+), 9 deletions(-) diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_fw.c b/drivers/net/ethernet/meta/fbnic/fbnic_fw.c index 0c55be7d25476..c7d255a095f0e 100644 --- a/drivers/net/ethernet/meta/fbnic/fbnic_fw.c +++ b/drivers/net/ethernet/meta/fbnic/fbnic_fw.c @@ -653,6 +653,9 @@ static int fbnic_fw_parse_cap_resp(void *opaque, struct fbnic_tlv_msg **results) fbd->fw_cap.anti_rollback_version = fta_get_uint(results, FBNIC_FW_CAP_RESP_ANTI_ROLLBACK_VERSION); + /* Always assume we need a BMC reinit */ + fbd->fw_cap.need_bmc_tcam_reinit = true; + return 0; } diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_fw.h b/drivers/net/ethernet/meta/fbnic/fbnic_fw.h index fde331696fdd7..e9a2bf489944a 100644 --- a/drivers/net/ethernet/meta/fbnic/fbnic_fw.h +++ b/drivers/net/ethernet/meta/fbnic/fbnic_fw.h @@ -51,8 +51,9 @@ struct fbnic_fw_cap { } stored; u8 active_slot; u8 bmc_mac_addr[4][ETH_ALEN]; - u8 bmc_present : 1; - u8 all_multi : 1; + u8 bmc_present : 1; + u8 need_bmc_tcam_reinit : 1; + u8 all_multi : 1; u8 link_speed; u8 link_fec; u32 anti_rollback_version; diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_pci.c b/drivers/net/ethernet/meta/fbnic/fbnic_pci.c index fac89860b1b7b..b3c27c566f526 100644 --- a/drivers/net/ethernet/meta/fbnic/fbnic_pci.c +++ b/drivers/net/ethernet/meta/fbnic/fbnic_pci.c @@ -206,6 +206,8 @@ static void fbnic_service_task(struct work_struct *work) fbnic_health_check(fbd); + fbnic_bmc_rpc_check(fbd); + if (netif_carrier_ok(fbd->netdev)) fbnic_napi_depletion_check(fbd->netdev); diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_rpc.c b/drivers/net/ethernet/meta/fbnic/fbnic_rpc.c index d5badaced6c3a..d821625d602ce 100644 --- a/drivers/net/ethernet/meta/fbnic/fbnic_rpc.c +++ b/drivers/net/ethernet/meta/fbnic/fbnic_rpc.c @@ -6,6 +6,7 @@ #include #include "fbnic.h" +#include "fbnic_fw.h" #include "fbnic_netdev.h" #include "fbnic_rpc.h" @@ -131,12 +132,9 @@ void fbnic_bmc_rpc_all_multi_config(struct fbnic_dev *fbd, else clear_bit(FBNIC_MAC_ADDR_T_ALLMULTI, mac_addr->act_tcam); - } else if (!test_bit(FBNIC_MAC_ADDR_T_BMC, mac_addr->act_tcam) && - !is_zero_ether_addr(mac_addr->mask.addr8) && - mac_addr->state == FBNIC_TCAM_S_VALID) { - clear_bit(FBNIC_MAC_ADDR_T_ALLMULTI, mac_addr->act_tcam); - clear_bit(FBNIC_MAC_ADDR_T_BMC, mac_addr->act_tcam); - mac_addr->state = FBNIC_TCAM_S_DELETE; + } else { + __fbnic_xc_unsync(mac_addr, FBNIC_MAC_ADDR_T_BMC); + __fbnic_xc_unsync(mac_addr, FBNIC_MAC_ADDR_T_ALLMULTI); } /* We have to add a special handler for multicast as the @@ -238,8 +236,15 @@ void fbnic_bmc_rpc_init(struct fbnic_dev *fbd) act_tcam->mask.tcam[j] = 0xffff; act_tcam->state = FBNIC_TCAM_S_UPDATE; +} - fbnic_bmc_rpc_all_multi_config(fbd, false); +void fbnic_bmc_rpc_check(struct fbnic_dev *fbd) +{ + if (fbd->fw_cap.need_bmc_tcam_reinit) { + fbnic_bmc_rpc_init(fbd); + __fbnic_set_rx_mode(fbd); + fbd->fw_cap.need_bmc_tcam_reinit = false; + } } #define FBNIC_ACT1_INIT(_l4, _udp, _ip, _v6) \ diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_rpc.h b/drivers/net/ethernet/meta/fbnic/fbnic_rpc.h index d9db7781a49b5..3d4925b2ac75d 100644 --- a/drivers/net/ethernet/meta/fbnic/fbnic_rpc.h +++ b/drivers/net/ethernet/meta/fbnic/fbnic_rpc.h @@ -184,6 +184,7 @@ struct fbnic_net; void fbnic_bmc_rpc_init(struct fbnic_dev *fbd); void fbnic_bmc_rpc_all_multi_config(struct fbnic_dev *fbd, bool enable_host); +void fbnic_bmc_rpc_check(struct fbnic_dev *fbd); void fbnic_reset_indir_tbl(struct fbnic_net *fbn); void fbnic_rss_key_fill(u32 *buffer); -- 2.47.3