diff options
| author | Paolo Abeni <pabeni@redhat.com> | 2026-04-21 13:50:26 +0300 |
|---|---|---|
| committer | Paolo Abeni <pabeni@redhat.com> | 2026-04-21 13:50:26 +0300 |
| commit | edaa48dc2c071cf2ab0611ee504bbd4c544fc178 (patch) | |
| tree | 20044ff1883003104534576496d228414979c4a0 /drivers | |
| parent | 4c1367a2d7aad643a6f87c6931b13cc1a25e8ca7 (diff) | |
| parent | c4dde411bc366f568dbe33366253bbfea049e8ea (diff) | |
| download | linux-edaa48dc2c071cf2ab0611ee504bbd4c544fc178.tar.xz | |
Merge branch 'net-sleepable-ndo_set_rx_mode'
Stanislav Fomichev says:
====================
net: sleepable ndo_set_rx_mode
This series adds a new ndo_set_rx_mode_async callback that enables
drivers to handle address list updates in a sleepable context. The
current ndo_set_rx_mode is called under the netif_addr_lock spinlock
with BHs disabled, which prevents drivers from sleeping. This is
problematic for ops-locked drivers that need to sleep.
The approach:
1. Add snapshot/reconcile infrastructure for address lists
2. Introduce dev_rx_mode_work that takes snapshots under the lock,
drops the lock, calls the driver, then reconciles changes back
3. Move promiscuity handling into the scheduled work as well
4. Convert existing ops-locked drivers to ndo_set_rx_mode_async
5. Add a warning for ops-locked drivers still using ndo_set_rx_mode
6. Add a selftest exercising the team+bridge+macvlan topology that
triggers the addr_lock -> ops_lock ordering issue
====================
Link: https://patch.msgid.link/20260416185712.2155425-1-sdf@fomichev.me
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/net/dummy.c | 6 | ||||
| -rw-r--r-- | drivers/net/ethernet/broadcom/bnxt/bnxt.c | 58 | ||||
| -rw-r--r-- | drivers/net/ethernet/intel/iavf/iavf_main.c | 16 | ||||
| -rw-r--r-- | drivers/net/ethernet/mellanox/mlx5/core/en/fs.h | 5 | ||||
| -rw-r--r-- | drivers/net/ethernet/mellanox/mlx5/core/en_fs.c | 32 | ||||
| -rw-r--r-- | drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 13 | ||||
| -rw-r--r-- | drivers/net/ethernet/meta/fbnic/fbnic_netdev.c | 20 | ||||
| -rw-r--r-- | drivers/net/ethernet/meta/fbnic/fbnic_netdev.h | 4 | ||||
| -rw-r--r-- | drivers/net/ethernet/meta/fbnic/fbnic_pci.c | 4 | ||||
| -rw-r--r-- | drivers/net/ethernet/meta/fbnic/fbnic_rpc.c | 2 | ||||
| -rw-r--r-- | drivers/net/netdevsim/netdev.c | 8 | ||||
| -rw-r--r-- | drivers/net/netkit.c | 6 |
12 files changed, 108 insertions, 66 deletions
diff --git a/drivers/net/dummy.c b/drivers/net/dummy.c index d6bdad4baadd..f8a4eb365c3d 100644 --- a/drivers/net/dummy.c +++ b/drivers/net/dummy.c @@ -47,7 +47,9 @@ static int numdummies = 1; /* fake multicast ability */ -static void set_multicast_list(struct net_device *dev) +static void set_multicast_list(struct net_device *dev, + struct netdev_hw_addr_list *uc, + struct netdev_hw_addr_list *mc) { } @@ -87,7 +89,7 @@ static const struct net_device_ops dummy_netdev_ops = { .ndo_init = dummy_dev_init, .ndo_start_xmit = dummy_xmit, .ndo_validate_addr = eth_validate_addr, - .ndo_set_rx_mode = set_multicast_list, + .ndo_set_rx_mode_async = set_multicast_list, .ndo_set_mac_address = eth_mac_addr, .ndo_get_stats64 = dummy_get_stats64, .ndo_change_carrier = dummy_change_carrier, diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index 2715632115a5..79e286621a28 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c @@ -11131,8 +11131,9 @@ static int bnxt_setup_nitroa0_vnic(struct bnxt *bp) return rc; } -static int bnxt_cfg_rx_mode(struct bnxt *); -static bool bnxt_mc_list_updated(struct bnxt *, u32 *); +static int bnxt_cfg_rx_mode(struct bnxt *, struct netdev_hw_addr_list *, bool); +static bool bnxt_mc_list_updated(struct bnxt *, u32 *, + const struct netdev_hw_addr_list *); static int bnxt_init_chip(struct bnxt *bp, bool irq_re_init) { @@ -11222,11 +11223,11 @@ static int bnxt_init_chip(struct bnxt *bp, bool irq_re_init) } else if (bp->dev->flags & IFF_MULTICAST) { u32 mask = 0; - bnxt_mc_list_updated(bp, &mask); + bnxt_mc_list_updated(bp, &mask, &bp->dev->mc); vnic->rx_mask |= mask; } - rc = bnxt_cfg_rx_mode(bp); + rc = bnxt_cfg_rx_mode(bp, &bp->dev->uc, true); if (rc) goto err_out; @@ -13620,17 +13621,17 @@ void bnxt_get_ring_drv_stats(struct bnxt *bp, bnxt_get_one_ring_drv_stats(bp, stats, &bp->bnapi[i]->cp_ring); } -static bool bnxt_mc_list_updated(struct bnxt *bp, u32 *rx_mask) +static bool bnxt_mc_list_updated(struct bnxt *bp, u32 *rx_mask, + const struct netdev_hw_addr_list *mc) { struct bnxt_vnic_info *vnic = &bp->vnic_info[BNXT_VNIC_DEFAULT]; - struct net_device *dev = bp->dev; struct netdev_hw_addr *ha; u8 *haddr; int mc_count = 0; bool update = false; int off = 0; - netdev_for_each_mc_addr(ha, dev) { + netdev_hw_addr_list_for_each(ha, mc) { if (mc_count >= BNXT_MAX_MC_ADDRS) { *rx_mask |= CFA_L2_SET_RX_MASK_REQ_MASK_ALL_MCAST; vnic->mc_list_count = 0; @@ -13654,17 +13655,17 @@ static bool bnxt_mc_list_updated(struct bnxt *bp, u32 *rx_mask) return update; } -static bool bnxt_uc_list_updated(struct bnxt *bp) +static bool bnxt_uc_list_updated(struct bnxt *bp, + const struct netdev_hw_addr_list *uc) { - struct net_device *dev = bp->dev; struct bnxt_vnic_info *vnic = &bp->vnic_info[BNXT_VNIC_DEFAULT]; struct netdev_hw_addr *ha; int off = 0; - if (netdev_uc_count(dev) != (vnic->uc_filter_count - 1)) + if (netdev_hw_addr_list_count(uc) != (vnic->uc_filter_count - 1)) return true; - netdev_for_each_uc_addr(ha, dev) { + netdev_hw_addr_list_for_each(ha, uc) { if (!ether_addr_equal(ha->addr, vnic->uc_list + off)) return true; @@ -13673,7 +13674,9 @@ static bool bnxt_uc_list_updated(struct bnxt *bp) return false; } -static void bnxt_set_rx_mode(struct net_device *dev) +static void bnxt_set_rx_mode(struct net_device *dev, + struct netdev_hw_addr_list *uc, + struct netdev_hw_addr_list *mc) { struct bnxt *bp = netdev_priv(dev); struct bnxt_vnic_info *vnic; @@ -13694,7 +13697,7 @@ static void bnxt_set_rx_mode(struct net_device *dev) if (dev->flags & IFF_PROMISC) mask |= CFA_L2_SET_RX_MASK_REQ_MASK_PROMISCUOUS; - uc_update = bnxt_uc_list_updated(bp); + uc_update = bnxt_uc_list_updated(bp, uc); if (dev->flags & IFF_BROADCAST) mask |= CFA_L2_SET_RX_MASK_REQ_MASK_BCAST; @@ -13702,27 +13705,23 @@ static void bnxt_set_rx_mode(struct net_device *dev) mask |= CFA_L2_SET_RX_MASK_REQ_MASK_ALL_MCAST; vnic->mc_list_count = 0; } else if (dev->flags & IFF_MULTICAST) { - mc_update = bnxt_mc_list_updated(bp, &mask); + mc_update = bnxt_mc_list_updated(bp, &mask, mc); } if (mask != vnic->rx_mask || uc_update || mc_update) { vnic->rx_mask = mask; - bnxt_queue_sp_work(bp, BNXT_RX_MASK_SP_EVENT); + bnxt_cfg_rx_mode(bp, uc, uc_update); } } -static int bnxt_cfg_rx_mode(struct bnxt *bp) +static int bnxt_cfg_rx_mode(struct bnxt *bp, struct netdev_hw_addr_list *uc, + bool uc_update) { struct net_device *dev = bp->dev; struct bnxt_vnic_info *vnic = &bp->vnic_info[BNXT_VNIC_DEFAULT]; struct netdev_hw_addr *ha; int i, off = 0, rc; - bool uc_update; - - netif_addr_lock_bh(dev); - uc_update = bnxt_uc_list_updated(bp); - netif_addr_unlock_bh(dev); if (!uc_update) goto skip_uc; @@ -13737,10 +13736,10 @@ static int bnxt_cfg_rx_mode(struct bnxt *bp) vnic->uc_filter_count = 1; netif_addr_lock_bh(dev); - if (netdev_uc_count(dev) > (BNXT_MAX_UC_ADDRS - 1)) { + if (netdev_hw_addr_list_count(uc) > (BNXT_MAX_UC_ADDRS - 1)) { vnic->rx_mask |= CFA_L2_SET_RX_MASK_REQ_MASK_PROMISCUOUS; } else { - netdev_for_each_uc_addr(ha, dev) { + netdev_hw_addr_list_for_each(ha, uc) { memcpy(vnic->uc_list + off, ha->addr, ETH_ALEN); off += ETH_ALEN; vnic->uc_filter_count++; @@ -14706,6 +14705,7 @@ static void bnxt_ulp_restart(struct bnxt *bp) static void bnxt_sp_task(struct work_struct *work) { struct bnxt *bp = container_of(work, struct bnxt, sp_task); + struct net_device *dev = bp->dev; set_bit(BNXT_STATE_IN_SP_TASK, &bp->state); smp_mb__after_atomic(); @@ -14719,9 +14719,6 @@ static void bnxt_sp_task(struct work_struct *work) bnxt_reenable_sriov(bp); } - if (test_and_clear_bit(BNXT_RX_MASK_SP_EVENT, &bp->sp_event)) - bnxt_cfg_rx_mode(bp); - if (test_and_clear_bit(BNXT_RX_NTP_FLTR_SP_EVENT, &bp->sp_event)) bnxt_cfg_ntp_filters(bp); if (test_and_clear_bit(BNXT_HWRM_EXEC_FWD_REQ_SP_EVENT, &bp->sp_event)) @@ -14786,6 +14783,13 @@ static void bnxt_sp_task(struct work_struct *work) /* These functions below will clear BNXT_STATE_IN_SP_TASK. They * must be the last functions to be called before exiting. */ + if (test_and_clear_bit(BNXT_RX_MASK_SP_EVENT, &bp->sp_event)) { + bnxt_lock_sp(bp); + if (test_bit(BNXT_STATE_OPEN, &bp->state)) + bnxt_cfg_rx_mode(bp, &dev->uc, true); + bnxt_unlock_sp(bp); + } + if (test_and_clear_bit(BNXT_RESET_TASK_SP_EVENT, &bp->sp_event)) bnxt_reset(bp, false); @@ -15986,7 +15990,7 @@ static const struct net_device_ops bnxt_netdev_ops = { .ndo_start_xmit = bnxt_start_xmit, .ndo_stop = bnxt_close, .ndo_get_stats64 = bnxt_get_stats64, - .ndo_set_rx_mode = bnxt_set_rx_mode, + .ndo_set_rx_mode_async = bnxt_set_rx_mode, .ndo_eth_ioctl = bnxt_ioctl, .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = bnxt_change_mac_addr, diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c index dad001abc908..3c1465cf0515 100644 --- a/drivers/net/ethernet/intel/iavf/iavf_main.c +++ b/drivers/net/ethernet/intel/iavf/iavf_main.c @@ -1150,14 +1150,18 @@ bool iavf_promiscuous_mode_changed(struct iavf_adapter *adapter) /** * iavf_set_rx_mode - NDO callback to set the netdev filters * @netdev: network interface device structure + * @uc: snapshot of uc address list + * @mc: snapshot of mc address list **/ -static void iavf_set_rx_mode(struct net_device *netdev) +static void iavf_set_rx_mode(struct net_device *netdev, + struct netdev_hw_addr_list *uc, + struct netdev_hw_addr_list *mc) { struct iavf_adapter *adapter = netdev_priv(netdev); spin_lock_bh(&adapter->mac_vlan_list_lock); - __dev_uc_sync(netdev, iavf_addr_sync, iavf_addr_unsync); - __dev_mc_sync(netdev, iavf_addr_sync, iavf_addr_unsync); + __hw_addr_sync_dev(uc, netdev, iavf_addr_sync, iavf_addr_unsync); + __hw_addr_sync_dev(mc, netdev, iavf_addr_sync, iavf_addr_unsync); spin_unlock_bh(&adapter->mac_vlan_list_lock); spin_lock_bh(&adapter->current_netdev_promisc_flags_lock); @@ -1210,7 +1214,9 @@ static void iavf_configure(struct iavf_adapter *adapter) struct net_device *netdev = adapter->netdev; int i; - iavf_set_rx_mode(netdev); + netif_addr_lock_bh(netdev); + iavf_set_rx_mode(netdev, &netdev->uc, &netdev->mc); + netif_addr_unlock_bh(netdev); iavf_configure_tx(adapter); iavf_configure_rx(adapter); @@ -5153,7 +5159,7 @@ static const struct net_device_ops iavf_netdev_ops = { .ndo_open = iavf_open, .ndo_stop = iavf_close, .ndo_start_xmit = iavf_xmit_frame, - .ndo_set_rx_mode = iavf_set_rx_mode, + .ndo_set_rx_mode_async = iavf_set_rx_mode, .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = iavf_set_mac, .ndo_change_mtu = iavf_change_mtu, diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/fs.h b/drivers/net/ethernet/mellanox/mlx5/core/en/fs.h index c3408b3f7010..091b80a67189 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en/fs.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/fs.h @@ -201,7 +201,10 @@ int mlx5e_add_vlan_trap(struct mlx5e_flow_steering *fs, int trap_id, int tir_nu void mlx5e_remove_vlan_trap(struct mlx5e_flow_steering *fs); int mlx5e_add_mac_trap(struct mlx5e_flow_steering *fs, int trap_id, int tir_num); void mlx5e_remove_mac_trap(struct mlx5e_flow_steering *fs); -void mlx5e_fs_set_rx_mode_work(struct mlx5e_flow_steering *fs, struct net_device *netdev); +void mlx5e_fs_set_rx_mode_work(struct mlx5e_flow_steering *fs, + struct net_device *netdev, + struct netdev_hw_addr_list *uc, + struct netdev_hw_addr_list *mc); int mlx5e_fs_vlan_rx_add_vid(struct mlx5e_flow_steering *fs, struct net_device *netdev, __be16 proto, u16 vid); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_fs.c b/drivers/net/ethernet/mellanox/mlx5/core/en_fs.c index fdfe9d1cfe21..12492c4a5d41 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_fs.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_fs.c @@ -609,20 +609,26 @@ static void mlx5e_execute_l2_action(struct mlx5e_flow_steering *fs, } static void mlx5e_sync_netdev_addr(struct mlx5e_flow_steering *fs, - struct net_device *netdev) + struct net_device *netdev, + struct netdev_hw_addr_list *uc, + struct netdev_hw_addr_list *mc) { struct netdev_hw_addr *ha; - netif_addr_lock_bh(netdev); + if (!uc || !mc) { + netif_addr_lock_bh(netdev); + mlx5e_sync_netdev_addr(fs, netdev, &netdev->uc, &netdev->mc); + netif_addr_unlock_bh(netdev); + return; + } mlx5e_add_l2_to_hash(fs->l2.netdev_uc, netdev->dev_addr); - netdev_for_each_uc_addr(ha, netdev) + + netdev_hw_addr_list_for_each(ha, uc) mlx5e_add_l2_to_hash(fs->l2.netdev_uc, ha->addr); - netdev_for_each_mc_addr(ha, netdev) + netdev_hw_addr_list_for_each(ha, mc) mlx5e_add_l2_to_hash(fs->l2.netdev_mc, ha->addr); - - netif_addr_unlock_bh(netdev); } static void mlx5e_fill_addr_array(struct mlx5e_flow_steering *fs, int list_type, @@ -724,7 +730,9 @@ static void mlx5e_apply_netdev_addr(struct mlx5e_flow_steering *fs) } static void mlx5e_handle_netdev_addr(struct mlx5e_flow_steering *fs, - struct net_device *netdev) + struct net_device *netdev, + struct netdev_hw_addr_list *uc, + struct netdev_hw_addr_list *mc) { struct mlx5e_l2_hash_node *hn; struct hlist_node *tmp; @@ -736,7 +744,7 @@ static void mlx5e_handle_netdev_addr(struct mlx5e_flow_steering *fs, hn->action = MLX5E_ACTION_DEL; if (fs->state_destroy) - mlx5e_sync_netdev_addr(fs, netdev); + mlx5e_sync_netdev_addr(fs, netdev, uc, mc); mlx5e_apply_netdev_addr(fs); } @@ -820,13 +828,15 @@ static void mlx5e_destroy_promisc_table(struct mlx5e_flow_steering *fs) } void mlx5e_fs_set_rx_mode_work(struct mlx5e_flow_steering *fs, - struct net_device *netdev) + struct net_device *netdev, + struct netdev_hw_addr_list *uc, + struct netdev_hw_addr_list *mc) { struct mlx5e_priv *priv = netdev_priv(netdev); struct mlx5e_l2_table *ea = &fs->l2; if (mlx5e_is_uplink_rep(priv)) { - mlx5e_handle_netdev_addr(fs, netdev); + mlx5e_handle_netdev_addr(fs, netdev, uc, mc); goto update_vport_context; } @@ -856,7 +866,7 @@ void mlx5e_fs_set_rx_mode_work(struct mlx5e_flow_steering *fs, if (enable_broadcast) mlx5e_add_l2_flow_rule(fs, &ea->broadcast, MLX5E_FULLMATCH); - mlx5e_handle_netdev_addr(fs, netdev); + mlx5e_handle_netdev_addr(fs, netdev, uc, mc); if (disable_broadcast) mlx5e_del_l2_flow_rule(fs, &ea->broadcast); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c index 6c4eeb88588c..5a46870c4b74 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c @@ -4145,11 +4145,13 @@ static void mlx5e_nic_set_rx_mode(struct mlx5e_priv *priv) queue_work(priv->wq, &priv->set_rx_mode_work); } -static void mlx5e_set_rx_mode(struct net_device *dev) +static void mlx5e_set_rx_mode(struct net_device *dev, + struct netdev_hw_addr_list *uc, + struct netdev_hw_addr_list *mc) { struct mlx5e_priv *priv = netdev_priv(dev); - mlx5e_nic_set_rx_mode(priv); + mlx5e_fs_set_rx_mode_work(priv->fs, dev, uc, mc); } static int mlx5e_set_mac(struct net_device *netdev, void *addr) @@ -5324,7 +5326,7 @@ const struct net_device_ops mlx5e_netdev_ops = { .ndo_setup_tc = mlx5e_setup_tc, .ndo_select_queue = mlx5e_select_queue, .ndo_get_stats64 = mlx5e_get_stats, - .ndo_set_rx_mode = mlx5e_set_rx_mode, + .ndo_set_rx_mode_async = mlx5e_set_rx_mode, .ndo_set_mac_address = mlx5e_set_mac, .ndo_vlan_rx_add_vid = mlx5e_vlan_rx_add_vid, .ndo_vlan_rx_kill_vid = mlx5e_vlan_rx_kill_vid, @@ -6309,8 +6311,11 @@ void mlx5e_set_rx_mode_work(struct work_struct *work) { struct mlx5e_priv *priv = container_of(work, struct mlx5e_priv, set_rx_mode_work); + struct net_device *dev = priv->netdev; - return mlx5e_fs_set_rx_mode_work(priv->fs, priv->netdev); + netdev_lock_ops(dev); + mlx5e_fs_set_rx_mode_work(priv->fs, dev, NULL, NULL); + netdev_unlock_ops(dev); } /* mlx5e generic netdev management API (move to en_common.c) */ diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c b/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c index b4b396ca9bce..c406a3b56b37 100644 --- a/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c +++ b/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c @@ -183,7 +183,9 @@ static int fbnic_mc_unsync(struct net_device *netdev, const unsigned char *addr) return ret; } -void __fbnic_set_rx_mode(struct fbnic_dev *fbd) +void __fbnic_set_rx_mode(struct fbnic_dev *fbd, + struct netdev_hw_addr_list *uc, + struct netdev_hw_addr_list *mc) { bool uc_promisc = false, mc_promisc = false; struct net_device *netdev = fbd->netdev; @@ -213,10 +215,10 @@ void __fbnic_set_rx_mode(struct fbnic_dev *fbd) } /* Synchronize unicast and multicast address lists */ - err = __dev_uc_sync(netdev, fbnic_uc_sync, fbnic_uc_unsync); + err = __hw_addr_sync_dev(uc, netdev, fbnic_uc_sync, fbnic_uc_unsync); if (err == -ENOSPC) uc_promisc = true; - err = __dev_mc_sync(netdev, fbnic_mc_sync, fbnic_mc_unsync); + err = __hw_addr_sync_dev(mc, netdev, fbnic_mc_sync, fbnic_mc_unsync); if (err == -ENOSPC) mc_promisc = true; @@ -238,18 +240,21 @@ void __fbnic_set_rx_mode(struct fbnic_dev *fbd) fbnic_write_tce_tcam(fbd); } -static void fbnic_set_rx_mode(struct net_device *netdev) +static void fbnic_set_rx_mode(struct net_device *netdev, + struct netdev_hw_addr_list *uc, + struct netdev_hw_addr_list *mc) { struct fbnic_net *fbn = netdev_priv(netdev); struct fbnic_dev *fbd = fbn->fbd; /* No need to update the hardware if we are not running */ if (netif_running(netdev)) - __fbnic_set_rx_mode(fbd); + __fbnic_set_rx_mode(fbd, uc, mc); } static int fbnic_set_mac(struct net_device *netdev, void *p) { + struct fbnic_net *fbn = netdev_priv(netdev); struct sockaddr *addr = p; if (!is_valid_ether_addr(addr->sa_data)) @@ -257,7 +262,8 @@ static int fbnic_set_mac(struct net_device *netdev, void *p) eth_hw_addr_set(netdev, addr->sa_data); - fbnic_set_rx_mode(netdev); + if (netif_running(netdev)) + __fbnic_set_rx_mode(fbn->fbd, &netdev->uc, &netdev->mc); return 0; } @@ -551,7 +557,7 @@ static const struct net_device_ops fbnic_netdev_ops = { .ndo_features_check = fbnic_features_check, .ndo_set_mac_address = fbnic_set_mac, .ndo_change_mtu = fbnic_change_mtu, - .ndo_set_rx_mode = fbnic_set_rx_mode, + .ndo_set_rx_mode_async = fbnic_set_rx_mode, .ndo_get_stats64 = fbnic_get_stats64, .ndo_bpf = fbnic_bpf, .ndo_hwtstamp_get = fbnic_hwtstamp_get, diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_netdev.h b/drivers/net/ethernet/meta/fbnic/fbnic_netdev.h index 9129a658f8fa..eded20b0e9e4 100644 --- a/drivers/net/ethernet/meta/fbnic/fbnic_netdev.h +++ b/drivers/net/ethernet/meta/fbnic/fbnic_netdev.h @@ -97,7 +97,9 @@ void fbnic_time_init(struct fbnic_net *fbn); int fbnic_time_start(struct fbnic_net *fbn); void fbnic_time_stop(struct fbnic_net *fbn); -void __fbnic_set_rx_mode(struct fbnic_dev *fbd); +void __fbnic_set_rx_mode(struct fbnic_dev *fbd, + struct netdev_hw_addr_list *uc, + struct netdev_hw_addr_list *mc); void fbnic_clear_rx_mode(struct fbnic_dev *fbd); void fbnic_phylink_get_pauseparam(struct net_device *netdev, diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_pci.c b/drivers/net/ethernet/meta/fbnic/fbnic_pci.c index b7c0b7349d00..7e85b480203c 100644 --- a/drivers/net/ethernet/meta/fbnic/fbnic_pci.c +++ b/drivers/net/ethernet/meta/fbnic/fbnic_pci.c @@ -135,7 +135,7 @@ void fbnic_up(struct fbnic_net *fbn) fbnic_rss_reinit_hw(fbn->fbd, fbn); - __fbnic_set_rx_mode(fbn->fbd); + __fbnic_set_rx_mode(fbn->fbd, &fbn->netdev->uc, &fbn->netdev->mc); /* Enable Tx/Rx processing */ fbnic_napi_enable(fbn); @@ -180,7 +180,7 @@ static int fbnic_fw_config_after_crash(struct fbnic_dev *fbd) } fbnic_rpc_reset_valid_entries(fbd); - __fbnic_set_rx_mode(fbd); + __fbnic_set_rx_mode(fbd, &fbd->netdev->uc, &fbd->netdev->mc); return 0; } diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_rpc.c b/drivers/net/ethernet/meta/fbnic/fbnic_rpc.c index 42a186db43ea..fe95b6f69646 100644 --- a/drivers/net/ethernet/meta/fbnic/fbnic_rpc.c +++ b/drivers/net/ethernet/meta/fbnic/fbnic_rpc.c @@ -244,7 +244,7 @@ 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); + __fbnic_set_rx_mode(fbd, &fbd->netdev->uc, &fbd->netdev->mc); fbd->fw_cap.need_bmc_tcam_reinit = false; } diff --git a/drivers/net/netdevsim/netdev.c b/drivers/net/netdevsim/netdev.c index e1541ca76715..a05af192caf3 100644 --- a/drivers/net/netdevsim/netdev.c +++ b/drivers/net/netdevsim/netdev.c @@ -185,7 +185,9 @@ out_drop_cnt: return NETDEV_TX_OK; } -static void nsim_set_rx_mode(struct net_device *dev) +static void nsim_set_rx_mode(struct net_device *dev, + struct netdev_hw_addr_list *uc, + struct netdev_hw_addr_list *mc) { } @@ -623,7 +625,7 @@ static const struct net_shaper_ops nsim_shaper_ops = { static const struct net_device_ops nsim_netdev_ops = { .ndo_start_xmit = nsim_start_xmit, - .ndo_set_rx_mode = nsim_set_rx_mode, + .ndo_set_rx_mode_async = nsim_set_rx_mode, .ndo_set_mac_address = eth_mac_addr, .ndo_validate_addr = eth_validate_addr, .ndo_change_mtu = nsim_change_mtu, @@ -648,7 +650,7 @@ static const struct net_device_ops nsim_netdev_ops = { static const struct net_device_ops nsim_vf_netdev_ops = { .ndo_start_xmit = nsim_start_xmit, - .ndo_set_rx_mode = nsim_set_rx_mode, + .ndo_set_rx_mode_async = nsim_set_rx_mode, .ndo_set_mac_address = eth_mac_addr, .ndo_validate_addr = eth_validate_addr, .ndo_change_mtu = nsim_change_mtu, diff --git a/drivers/net/netkit.c b/drivers/net/netkit.c index 7b56a7ad7a49..5e2eecc3165d 100644 --- a/drivers/net/netkit.c +++ b/drivers/net/netkit.c @@ -186,7 +186,9 @@ static int netkit_get_iflink(const struct net_device *dev) return iflink; } -static void netkit_set_multicast(struct net_device *dev) +static void netkit_set_multicast(struct net_device *dev, + struct netdev_hw_addr_list *uc, + struct netdev_hw_addr_list *mc) { /* Nothing to do, we receive whatever gets pushed to us! */ } @@ -330,7 +332,7 @@ static const struct net_device_ops netkit_netdev_ops = { .ndo_open = netkit_open, .ndo_stop = netkit_close, .ndo_start_xmit = netkit_xmit, - .ndo_set_rx_mode = netkit_set_multicast, + .ndo_set_rx_mode_async = netkit_set_multicast, .ndo_set_rx_headroom = netkit_set_headroom, .ndo_set_mac_address = netkit_set_macaddr, .ndo_get_iflink = netkit_get_iflink, |
