]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
fbnic: Add logic to repopulate RPC TCAM if BMC enables channel
authorAlexander Duyck <alexanderduyck@fb.com>
Tue, 26 Aug 2025 19:45:01 +0000 (12:45 -0700)
committerPaolo Abeni <pabeni@redhat.com>
Thu, 28 Aug 2025 12:51:07 +0000 (14:51 +0200)
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 <alexanderduyck@fb.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/175623750101.2246365.8518307324797058580.stgit@ahduyck-xeon-server.home.arpa
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
drivers/net/ethernet/meta/fbnic/fbnic_fw.c
drivers/net/ethernet/meta/fbnic/fbnic_fw.h
drivers/net/ethernet/meta/fbnic/fbnic_pci.c
drivers/net/ethernet/meta/fbnic/fbnic_rpc.c
drivers/net/ethernet/meta/fbnic/fbnic_rpc.h

index 0c55be7d2547614c06d32c386ba2502a142ee0b0..c7d255a095f0ecf97f0b17136ad8df690582c54a 100644 (file)
@@ -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;
 }
 
index fde331696fdd7fa2e2edd9db16cf5bf68d20b046..e9a2bf489944ac4596d7a1bada0be9293e811089 100644 (file)
@@ -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;
index fac89860b1b7bcc62a939f12b9684ec3db67d262..b3c27c566f526f84b715f29e8300351922f15851 100644 (file)
@@ -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);
 
index d5badaced6c3a62ea469014dc89e0ba47a96b587..d821625d602cedd5adb551449a64fa219f2b2ad2 100644 (file)
@@ -6,6 +6,7 @@
 #include <net/ipv6.h>
 
 #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)           \
index d9db7781a49b5104ffde6edadb17fe2570ead2ae..3d4925b2ac75dcb958fe08ec3ae72e61728d8020 100644 (file)
@@ -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);