Implement the ndo_set_rx_mode_async callback and update
the driver to use the snapshot/commit model for RX mode update.
Signed-off-by: I Viswanath <viswanathiyyappan@gmail.com>
---
Call paths involving netif_set_rx_mode in vmxnet3
netif_set_rx_mode
`-- vmxnet3_activate_dev
|-- vmxnet3_open (ndo_open, takes lock)
|-- vmxnet3_change_mtu (ndo_change_mtu, takes lock)
|-- vmxnet3_reset_work (takes lock)
|-- vmxnet3_resume (lock added)
|-- vmxnet3_set_ringparam (ethtool callback, takes lock)
`-- vmxnet3_xdp_set
`-- vmxnet3_xdp (ndo_bpf, takes lock)
drivers/net/vmxnet3/vmxnet3_drv.c | 46 +++++++++++++++++++++++--------
1 file changed, 35 insertions(+), 11 deletions(-)
diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c
index 40522afc0532..350e44286c00 100644
--- a/drivers/net/vmxnet3/vmxnet3_drv.c
+++ b/drivers/net/vmxnet3/vmxnet3_drv.c
@@ -2775,18 +2775,18 @@ static u8 *
vmxnet3_copy_mc(struct net_device *netdev)
{
u8 *buf = NULL;
- u32 sz = netdev_mc_count(netdev) * ETH_ALEN;
+ u32 sz = netif_rx_mode_mc_count(netdev) * ETH_ALEN;
+ char *ha_addr;
+ int ni;
/* struct Vmxnet3_RxFilterConf.mfTableLen is u16. */
if (sz <= 0xffff) {
/* We may be called with BH disabled */
buf = kmalloc(sz, GFP_ATOMIC);
if (buf) {
- struct netdev_hw_addr *ha;
int i = 0;
-
- netdev_for_each_mc_addr(ha, netdev)
- memcpy(buf + i++ * ETH_ALEN, ha->addr,
+ netif_rx_mode_for_each_mc_addr(ha_addr, netdev, ni)
+ memcpy(buf + i++ * ETH_ALEN, ha_addr,
ETH_ALEN);
}
}
@@ -2796,8 +2796,23 @@ vmxnet3_copy_mc(struct net_device *netdev)
static void
vmxnet3_set_mc(struct net_device *netdev)
+{
+ bool allmulti = !!(netdev->flags & IFF_ALLMULTI);
+ bool promisc = !!(netdev->flags & IFF_PROMISC);
+ bool broadcast = !!(netdev->flags & IFF_BROADCAST);
+
+ netif_set_rx_mode_flag(netdev, NETIF_RX_MODE_UC_SKIP, true);
+ netif_set_rx_mode_flag(netdev, NETIF_RX_MODE_MC_SKIP, allmulti);
+
+ netif_set_rx_mode_cfg(netdev, NETIF_RX_MODE_CFG_ALLMULTI, allmulti);
+ netif_set_rx_mode_cfg(netdev, NETIF_RX_MODE_CFG_PROMISC, promisc);
+ netif_set_rx_mode_cfg(netdev, NETIF_RX_MODE_CFG_BROADCAST, broadcast);
+}
+
+static void vmxnet3_set_mc_async(struct net_device *netdev)
{
struct vmxnet3_adapter *adapter = netdev_priv(netdev);
+ int mc_count = netif_rx_mode_mc_count(netdev);
unsigned long flags;
struct Vmxnet3_RxFilterConf *rxConf =
&adapter->shared->devRead.rxFilterConf;
@@ -2806,7 +2821,7 @@ vmxnet3_set_mc(struct net_device *netdev)
bool new_table_pa_valid = false;
u32 new_mode = VMXNET3_RXM_UCAST;
- if (netdev->flags & IFF_PROMISC) {
+ if (netif_get_rx_mode_cfg(netdev, NETIF_RX_MODE_CFG_PROMISC)) {
u32 *vfTable = adapter->shared->devRead.rxFilterConf.vfTable;
memset(vfTable, 0, VMXNET3_VFT_SIZE * sizeof(*vfTable));
@@ -2815,16 +2830,16 @@ vmxnet3_set_mc(struct net_device *netdev)
vmxnet3_restore_vlan(adapter);
}
- if (netdev->flags & IFF_BROADCAST)
+ if (netif_get_rx_mode_cfg(netdev, NETIF_RX_MODE_CFG_BROADCAST))
new_mode |= VMXNET3_RXM_BCAST;
- if (netdev->flags & IFF_ALLMULTI)
+ if (netif_get_rx_mode_cfg(netdev, NETIF_RX_MODE_CFG_ALLMULTI))
new_mode |= VMXNET3_RXM_ALL_MULTI;
else
- if (!netdev_mc_empty(netdev)) {
+ if (mc_count) {
new_table = vmxnet3_copy_mc(netdev);
if (new_table) {
- size_t sz = netdev_mc_count(netdev) * ETH_ALEN;
+ size_t sz = mc_count * ETH_ALEN;
rxConf->mfTableLen = cpu_to_le16(sz);
new_table_pa = dma_map_single(
@@ -3213,7 +3228,7 @@ vmxnet3_activate_dev(struct vmxnet3_adapter *adapter)
}
/* Apply the rx filter settins last. */
- vmxnet3_set_mc(adapter->netdev);
+ netif_set_rx_mode(adapter->netdev);
/*
* Check link state when first activating device. It will start the
@@ -3977,6 +3992,7 @@ vmxnet3_probe_device(struct pci_dev *pdev,
.ndo_get_stats64 = vmxnet3_get_stats64,
.ndo_tx_timeout = vmxnet3_tx_timeout,
.ndo_set_rx_mode = vmxnet3_set_mc,
+ .ndo_set_rx_mode_async = vmxnet3_set_mc_async,
.ndo_vlan_rx_add_vid = vmxnet3_vlan_rx_add_vid,
.ndo_vlan_rx_kill_vid = vmxnet3_vlan_rx_kill_vid,
#ifdef CONFIG_NET_POLL_CONTROLLER
@@ -4400,6 +4416,7 @@ static void vmxnet3_shutdown_device(struct pci_dev *pdev)
vmxnet3_disable_all_intrs(adapter);
clear_bit(VMXNET3_STATE_BIT_RESETTING, &adapter->state);
+ netif_disable_async_ops(netdev);
}
@@ -4518,6 +4535,7 @@ vmxnet3_suspend(struct device *device)
pci_disable_device(pdev);
pci_set_power_state(pdev, pci_choose_state(pdev, PMSG_SUSPEND));
+ netif_disable_async_ops(netdev);
return 0;
}
@@ -4531,6 +4549,8 @@ vmxnet3_resume(struct device *device)
struct net_device *netdev = pci_get_drvdata(pdev);
struct vmxnet3_adapter *adapter = netdev_priv(netdev);
+ netif_enable_async_ops(netdev);
+
if (!netif_running(netdev))
return 0;
@@ -4559,7 +4579,11 @@ vmxnet3_resume(struct device *device)
vmxnet3_rq_cleanup_all(adapter);
vmxnet3_reset_dev(adapter);
+
+ rtnl_lock();
err = vmxnet3_activate_dev(adapter);
+ rtnl_unlock();
+
if (err != 0) {
netdev_err(netdev,
"failed to re-activate on resume, error: %d", err);
--
2.47.3
> -----Original Message-----
> From: Intel-wired-lan <intel-wired-lan-bounces@osuosl.org> On Behalf
> Of I Viswanath
> Sent: Saturday, March 14, 2026 7:28 PM
> To: stfomichev@gmail.com; horms@kernel.org; edumazet@google.com;
> pabeni@redhat.com; andrew+netdev@lunn.ch; kuba@kernel.org;
> davem@davemloft.net; eperezma@redhat.com; xuanzhuo@linux.alibaba.com;
> jasowang@redhat.com; mst@redhat.com; Kitszel, Przemyslaw
> <przemyslaw.kitszel@intel.com>; Nguyen, Anthony L
> <anthony.l.nguyen@intel.com>; Keller, Jacob E
> <jacob.e.keller@intel.com>; ronak.doshi@broadcom.com;
> pcnet32@frontier.com
> Cc: bcm-kernel-feedback-list@broadcom.com; netdev@vger.kernel.org;
> virtualization@lists.linux.dev; intel-wired-lan@lists.osuosl.org;
> linux-kernel@vger.kernel.org; I Viswanath
> <viswanathiyyappan@gmail.com>
> Subject: [Intel-wired-lan] [PATCH net-next v9 6/7] vmxnet3: Implement
> ndo_set_rx_mode_async callback
>
> Implement the ndo_set_rx_mode_async callback and update the driver to
> use the snapshot/commit model for RX mode update.
>
> Signed-off-by: I Viswanath <viswanathiyyappan@gmail.com>
> ---
>
> Call paths involving netif_set_rx_mode in vmxnet3
>
> netif_set_rx_mode
> `-- vmxnet3_activate_dev
> |-- vmxnet3_open (ndo_open, takes lock)
> |-- vmxnet3_change_mtu (ndo_change_mtu, takes lock)
> |-- vmxnet3_reset_work (takes lock)
> |-- vmxnet3_resume (lock added)
> |-- vmxnet3_set_ringparam (ethtool callback, takes lock)
> `-- vmxnet3_xdp_set
> `-- vmxnet3_xdp (ndo_bpf, takes lock)
>
> drivers/net/vmxnet3/vmxnet3_drv.c | 46 +++++++++++++++++++++++-------
> -
> 1 file changed, 35 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c
> b/drivers/net/vmxnet3/vmxnet3_drv.c
> index 40522afc0532..350e44286c00 100644
> --- a/drivers/net/vmxnet3/vmxnet3_drv.c
> +++ b/drivers/net/vmxnet3/vmxnet3_drv.c
> @@ -2775,18 +2775,18 @@ static u8 *
> vmxnet3_copy_mc(struct net_device *netdev) {
> u8 *buf = NULL;
...
> err);
> --
> 2.47.3
Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
© 2016 - 2026 Red Hat, Inc.