From: I Viswanath <viswanathiyyappan@gmail.com>
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,
przemyslaw.kitszel@intel.com, anthony.l.nguyen@intel.com,
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: [PATCH net-next v9 4/7] e1000: Implement ndo_set_rx_mode_async callback
Date: Sat, 14 Mar 2026 23:58:06 +0530 [thread overview]
Message-ID: <20260314182809.362808-5-viswanathiyyappan@gmail.com> (raw)
In-Reply-To: <20260314182809.362808-1-viswanathiyyappan@gmail.com>
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 e1000
netif_set_rx_mode
|-- __e1000_shutdown (lock added)
|
`-- e1000_configure
|-- e1000_open (ndo_open, takes lock)
|
`-- e1000_up
|-- e1000_reinit_locked
| |-- e1000_set_features (ndo_set_features, takes lock)
| |-- e1000_reset_task (ethtool callback, takes lock)
| |-- e1000_mii_ioctl
| | `-- e1000_ioctl (ndo_do_ioctl, takes lock)
| `-- e1000_nway_reset (ethtool callback, takes lock)
|
|-- e1000_change_mtu (ndo_change_mtu, takes lock)
|-- e1000_resume (lock added)
|-- e1000_io_resume (lock added)
|
|-- e1000_set_link_ksettings (ethtool callback, takes lock)
|-- e1000_set_pauseparam (ethtool callback, takes lock)
`-- e1000_set_ringparam (ethtool callback, takes lock)
drivers/net/ethernet/intel/e1000/e1000_main.c | 77 ++++++++++++++-----
1 file changed, 59 insertions(+), 18 deletions(-)
diff --git a/drivers/net/ethernet/intel/e1000/e1000_main.c b/drivers/net/ethernet/intel/e1000/e1000_main.c
index 9b09eb144b81..ec25b41c63b7 100644
--- a/drivers/net/ethernet/intel/e1000/e1000_main.c
+++ b/drivers/net/ethernet/intel/e1000/e1000_main.c
@@ -99,6 +99,7 @@ static void e1000_clean_tx_ring(struct e1000_adapter *adapter,
static void e1000_clean_rx_ring(struct e1000_adapter *adapter,
struct e1000_rx_ring *rx_ring);
static void e1000_set_rx_mode(struct net_device *netdev);
+static void e1000_set_rx_mode_async(struct net_device *netdev);
static void e1000_update_phy_info_task(struct work_struct *work);
static void e1000_watchdog(struct work_struct *work);
static void e1000_82547_tx_fifo_stall_task(struct work_struct *work);
@@ -359,7 +360,7 @@ static void e1000_configure(struct e1000_adapter *adapter)
struct net_device *netdev = adapter->netdev;
int i;
- e1000_set_rx_mode(netdev);
+ netif_set_rx_mode(netdev);
e1000_restore_vlan(adapter);
e1000_init_manageability(adapter);
@@ -823,6 +824,7 @@ static const struct net_device_ops e1000_netdev_ops = {
.ndo_stop = e1000_close,
.ndo_start_xmit = e1000_xmit_frame,
.ndo_set_rx_mode = e1000_set_rx_mode,
+ .ndo_set_rx_mode_async = e1000_set_rx_mode_async,
.ndo_set_mac_address = e1000_set_mac,
.ndo_tx_timeout = e1000_tx_timeout,
.ndo_change_mtu = e1000_change_mtu,
@@ -2223,23 +2225,44 @@ static int e1000_set_mac(struct net_device *netdev, void *p)
}
/**
- * e1000_set_rx_mode - Secondary Unicast, Multicast and Promiscuous mode set
+ * e1000_set_rx_mode - Secondary Unicast, Multicast and Promiscuous mode
+ * config.
* @netdev: network interface device structure
*
* The set_rx_mode entry point is called whenever the unicast or multicast
* address lists or the network interface flags are updated. This routine is
- * responsible for configuring the hardware for proper unicast, multicast,
- * promiscuous mode, and all-multi behavior.
+ * responsible for preparing the rx mode config and scheduling the rx_mode
+ * work which invokes the set_rx_mode_async callback.
**/
static void e1000_set_rx_mode(struct net_device *netdev)
+{
+ bool allmulti = !!(netdev->flags & IFF_ALLMULTI);
+ bool promisc = !!(netdev->flags & IFF_PROMISC);
+
+ netif_set_rx_mode_flag(netdev, NETIF_RX_MODE_UC_SKIP, promisc);
+
+ netif_set_rx_mode_cfg(netdev, NETIF_RX_MODE_CFG_ALLMULTI, allmulti);
+ netif_set_rx_mode_cfg(netdev, NETIF_RX_MODE_CFG_PROMISC, promisc);
+}
+
+/**
+ * e1000_set_rx_mode_async - Secondary Unicast, Multicast and Promiscuous mode
+ * confirm.
+ * @netdev: network interface device structure
+ *
+ * The set_rx_mode_async callback is responsible for actually updating the
+ * hardware. This routine is responsible for configuring the hardware for
+ * proper unicast, multicast, promiscuous mode, and all-multi behavior.
+ **/
+static void e1000_set_rx_mode_async(struct net_device *netdev)
{
struct e1000_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw;
- struct netdev_hw_addr *ha;
bool use_uc = false;
+ char *ha_addr;
u32 rctl;
u32 hash_value;
- int i, rar_entries = E1000_RAR_ENTRIES;
+ int i, rar_entries = E1000_RAR_ENTRIES, ni;
int mta_reg_count = E1000_NUM_MTA_REGISTERS;
u32 *mcarray = kcalloc(mta_reg_count, sizeof(u32), GFP_ATOMIC);
@@ -2250,11 +2273,11 @@ static void e1000_set_rx_mode(struct net_device *netdev)
rctl = er32(RCTL);
- if (netdev->flags & IFF_PROMISC) {
+ if (netif_get_rx_mode_cfg(netdev, NETIF_RX_MODE_CFG_PROMISC)) {
rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE);
rctl &= ~E1000_RCTL_VFE;
} else {
- if (netdev->flags & IFF_ALLMULTI)
+ if (netif_get_rx_mode_cfg(netdev, NETIF_RX_MODE_CFG_ALLMULTI))
rctl |= E1000_RCTL_MPE;
else
rctl &= ~E1000_RCTL_MPE;
@@ -2263,9 +2286,9 @@ static void e1000_set_rx_mode(struct net_device *netdev)
rctl |= E1000_RCTL_VFE;
}
- if (netdev_uc_count(netdev) > rar_entries - 1) {
+ if (netif_rx_mode_uc_count(netdev) > rar_entries - 1) {
rctl |= E1000_RCTL_UPE;
- } else if (!(netdev->flags & IFF_PROMISC)) {
+ } else if (!netif_get_rx_mode_cfg(netdev, NETIF_RX_MODE_CFG_PROMISC)) {
rctl &= ~E1000_RCTL_UPE;
use_uc = true;
}
@@ -2286,23 +2309,23 @@ static void e1000_set_rx_mode(struct net_device *netdev)
*/
i = 1;
if (use_uc)
- netdev_for_each_uc_addr(ha, netdev) {
+ netif_rx_mode_for_each_uc_addr(ha_addr, netdev, ni) {
if (i == rar_entries)
break;
- e1000_rar_set(hw, ha->addr, i++);
+ e1000_rar_set(hw, ha_addr, i++);
}
- netdev_for_each_mc_addr(ha, netdev) {
+ netif_rx_mode_for_each_mc_addr(ha_addr, netdev, ni) {
if (i == rar_entries) {
/* load any remaining addresses into the hash table */
u32 hash_reg, hash_bit, mta;
- hash_value = e1000_hash_mc_addr(hw, ha->addr);
+ hash_value = e1000_hash_mc_addr(hw, ha_addr);
hash_reg = (hash_value >> 5) & 0x7F;
hash_bit = hash_value & 0x1F;
mta = (1 << hash_bit);
mcarray[hash_reg] |= mta;
} else {
- e1000_rar_set(hw, ha->addr, i++);
+ e1000_rar_set(hw, ha_addr, i++);
}
}
@@ -5092,7 +5115,10 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake)
if (wufc) {
e1000_setup_rctl(adapter);
- e1000_set_rx_mode(netdev);
+
+ rtnl_lock();
+ netif_set_rx_mode(netdev);
+ rtnl_unlock();
rctl = er32(RCTL);
@@ -5150,11 +5176,13 @@ static int e1000_suspend(struct device *dev)
{
int retval;
struct pci_dev *pdev = to_pci_dev(dev);
+ struct net_device *netdev = pci_get_drvdata(pdev);
bool wake;
retval = __e1000_shutdown(pdev, &wake);
device_set_wakeup_enable(dev, wake);
+ netif_disable_async_ops(netdev);
return retval;
}
@@ -5166,6 +5194,8 @@ static int e1000_resume(struct device *dev)
struct e1000_hw *hw = &adapter->hw;
u32 err;
+ netif_enable_async_ops(netdev);
+
if (adapter->need_ioport)
err = pci_enable_device(pdev);
else
@@ -5195,8 +5225,11 @@ static int e1000_resume(struct device *dev)
e1000_init_manageability(adapter);
- if (netif_running(netdev))
+ if (netif_running(netdev)) {
+ rtnl_lock();
e1000_up(adapter);
+ rtnl_unlock();
+ }
netif_device_attach(netdev);
@@ -5205,6 +5238,7 @@ static int e1000_resume(struct device *dev)
static void e1000_shutdown(struct pci_dev *pdev)
{
+ struct net_device *netdev = pci_get_drvdata(pdev);
bool wake;
__e1000_shutdown(pdev, &wake);
@@ -5213,6 +5247,8 @@ static void e1000_shutdown(struct pci_dev *pdev)
pci_wake_from_d3(pdev, wake);
pci_set_power_state(pdev, PCI_D3hot);
}
+
+ netif_disable_async_ops(netdev);
}
#ifdef CONFIG_NET_POLL_CONTROLLER
@@ -5312,11 +5348,16 @@ static void e1000_io_resume(struct pci_dev *pdev)
{
struct net_device *netdev = pci_get_drvdata(pdev);
struct e1000_adapter *adapter = netdev_priv(netdev);
+ int rc;
e1000_init_manageability(adapter);
if (netif_running(netdev)) {
- if (e1000_up(adapter)) {
+ rtnl_lock();
+ rc = e1000_up(adapter);
+ rtnl_unlock();
+
+ if (rc) {
pr_info("can't bring device back up after reset\n");
return;
}
--
2.47.3
next prev parent reply other threads:[~2026-03-14 18:29 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-14 18:28 [PATCH net-next v9 0/7] Introduce async callback ndo_set_rx_mode_async I Viswanath
2026-03-14 18:28 ` [PATCH net-next v9 1/7] net: core: Add state tracking for async netdev ops I Viswanath
2026-03-16 7:25 ` [Intel-wired-lan] " Loktionov, Aleksandr
2026-03-14 18:28 ` [PATCH net-next v9 2/7] net: core: Introduce callback ndo_set_rx_mode_async I Viswanath
2026-03-16 7:29 ` [Intel-wired-lan] " Loktionov, Aleksandr
2026-03-14 18:28 ` [PATCH net-next v9 3/7] virtio-net: Implement ndo_set_rx_mode_async callback I Viswanath
2026-03-16 7:30 ` [Intel-wired-lan] " Loktionov, Aleksandr
2026-03-14 18:28 ` I Viswanath [this message]
2026-03-16 7:30 ` [Intel-wired-lan] [PATCH net-next v9 4/7] e1000: " Loktionov, Aleksandr
2026-03-14 18:28 ` [PATCH net-next v9 5/7] 8139cp: " I Viswanath
2026-03-16 7:34 ` [Intel-wired-lan] " Loktionov, Aleksandr
2026-03-14 18:28 ` [PATCH net-next v9 6/7] vmxnet3: " I Viswanath
2026-03-16 7:35 ` [Intel-wired-lan] " Loktionov, Aleksandr
2026-03-14 18:28 ` [PATCH net-next v9 7/7] pcnet32: " I Viswanath
2026-03-16 7:35 ` [Intel-wired-lan] " Loktionov, Aleksandr
2026-03-14 20:06 ` [PATCH net-next v9 0/7] Introduce async callback ndo_set_rx_mode_async Jakub Kicinski
2026-03-14 19:59 ` I Viswanath
2026-03-17 16:15 ` Jakub Kicinski
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260314182809.362808-5-viswanathiyyappan@gmail.com \
--to=viswanathiyyappan@gmail.com \
--cc=andrew+netdev@lunn.ch \
--cc=anthony.l.nguyen@intel.com \
--cc=bcm-kernel-feedback-list@broadcom.com \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=eperezma@redhat.com \
--cc=horms@kernel.org \
--cc=intel-wired-lan@lists.osuosl.org \
--cc=jacob.e.keller@intel.com \
--cc=jasowang@redhat.com \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mst@redhat.com \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=pcnet32@frontier.com \
--cc=przemyslaw.kitszel@intel.com \
--cc=ronak.doshi@broadcom.com \
--cc=stfomichev@gmail.com \
--cc=virtualization@lists.linux.dev \
--cc=xuanzhuo@linux.alibaba.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox