From: wei.fang@oss.nxp.com
To: claudiu.manoil@nxp.com, vladimir.oltean@nxp.com,
xiaoning.wang@nxp.com, andrew@lunn.ch, olteanv@gmail.com,
andrew+netdev@lunn.ch, davem@davemloft.net, edumazet@google.com,
kuba@kernel.org, pabeni@redhat.com, linux@armlinux.org.uk
Cc: wei.fang@nxp.com, imx@lists.linux.dev, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org
Subject: [PATCH v3 net-next 13/15] net: enetc: implement ndo_set_rx_mode_async for ENETC v4 VF
Date: Mon, 31 Aug 2026 10:54:39 +0800 [thread overview]
Message-ID: <20260831025441.635045-14-wei.fang@oss.nxp.com> (raw)
In-Reply-To: <20260831025441.635045-1-wei.fang@oss.nxp.com>
From: Wei Fang <wei.fang@nxp.com>
The ENETC VF communicates MAC filter changes to the PF driver via a VSI
mailbox interface. The message send path in enetc_msg_vsi_send() polls
for completion with a timeout up to 200ms, which requires a sleepable
context.
The legacy ndo_set_rx_mode callback is invoked with netif_addr_lock_bh
held and BH disabled, making it incompatible with the VSI messaging path.
Implement ndo_set_rx_mode_async instead, which runs from a workqueue with
rtnl_lock held in a fully sleepable context, and receives pre-snapshotted
unicast and multicast address lists from the networking core.
Add enetc_vf_set_mac_promisc() to send a MAC promiscuous mode message to
the PF. The message specifies the filter type (unicast, multicast, or
both) and whether to enable promiscuous mode and clear existing MAC hash
filter.
Add enetc_vf_set_mac_hash_filter() to send a 64-bit Bloom filter hash
table to the PF. Each filter type (UC or MC) contributes two u32 entries
representing the low and high halves of its 64-bit hash bitmap. The
function accepts pre-snapshotted address lists from the framework and
iterates them with netdev_hw_addr_list_for_each(). When IFF_PROMISC is
active, hash filter programming is skipped since promiscuous mode already
accepts all frames.
The ndo_set_rx_mode_async callback selects the appropriate filter
configuration based on the current netdev flags:
- IFF_PROMISC: enable full promiscuous mode for both unicast and
multicast
- IFF_ALLMULTI: enable multicast promiscuous mode, disable unicast
promiscuous mode, and apply a unicast hash filter
- otherwise: disable all promiscuous modes and apply both
unicast and multicast hash filters
Set IFF_UNICAST_FLT in priv_flags for ENETC v4 VFs so the network stack
does not fall back to full promiscuous mode unnecessarily when unicast
address filtering is supported by the hardware.
This feature applies to ENETC v4 hardware only. ENETC v1 (LS1028A) does
not support VF-PF MAC filter messaging and the callback returns early
for such devices.
Signed-off-by: Wei Fang <wei.fang@nxp.com>
---
.../net/ethernet/freescale/enetc/enetc_vf.c | 140 ++++++++++++++++++
1 file changed, 140 insertions(+)
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_vf.c b/drivers/net/ethernet/freescale/enetc/enetc_vf.c
index 322705202d49..4e717afba7f7 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_vf.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc_vf.c
@@ -213,6 +213,142 @@ static int enetc_vf_setup_tc(struct net_device *ndev, enum tc_setup_type type,
}
}
+static int enetc_vf_set_mac_promisc(struct enetc_si *si, int type, bool en)
+{
+ struct enetc_msg_mac_promisc_mode *msg;
+ struct device *dev = &si->pdev->dev;
+ struct enetc_msg_swbd msg_swbd;
+
+ if (!(type & ENETC_MAC_FILTER_TYPE_ALL))
+ return -EINVAL;
+
+ msg_swbd.size = ALIGN(sizeof(*msg), ENETC_MSG_ALIGN);
+ msg_swbd.vaddr = dma_alloc_coherent(dev, msg_swbd.size,
+ &msg_swbd.dma, GFP_KERNEL);
+ if (!msg_swbd.vaddr)
+ return -ENOMEM;
+
+ msg = (struct enetc_msg_mac_promisc_mode *)msg_swbd.vaddr;
+ msg->config = FIELD_PREP(ENETC_MSG_MAC_TYPE,
+ type & ENETC_MAC_FILTER_TYPE_ALL);
+ msg->config |= FIELD_PREP(ENETC_MSG_MAC_PROMISC_MODE, en);
+ msg->config |= FIELD_PREP(ENETC_MSG_MAC_FLUSH_MACS, en);
+ enetc_msg_fill_common_hdr(&msg_swbd, ENETC_MSG_CLASS_ID_MAC_FILTER,
+ ENETC_MSG_SET_MAC_PROMISC_MODE, 0, 0);
+
+ return enetc_msg_vsi_send(si, &msg_swbd);
+}
+
+static int enetc_vf_set_mac_hash_filter(struct enetc_si *si,
+ struct netdev_hw_addr_list *uc,
+ struct netdev_hw_addr_list *mc)
+{
+ struct enetc_msg_mac_hash_filter *msg;
+ struct enetc_mac_filter *mac_filter;
+ struct device *dev = &si->pdev->dev;
+ struct net_device *ndev = si->ndev;
+ struct enetc_msg_swbd msg_swbd;
+ struct netdev_hw_addr *ha;
+ u32 msg_size, tbl_cnt;
+ int mac_filter_type;
+ int i = 0;
+
+ if (ndev->flags & IFF_PROMISC)
+ return 0;
+
+ if (ndev->flags & IFF_ALLMULTI) {
+ tbl_cnt = 2;
+ mac_filter_type = ENETC_MAC_FILTER_TYPE_UC;
+ } else {
+ tbl_cnt = 4;
+ mac_filter_type = ENETC_MAC_FILTER_TYPE_ALL;
+ }
+
+ msg_size = struct_size(msg, hash_tbl, tbl_cnt);
+ msg_swbd.size = ALIGN(msg_size, ENETC_MSG_ALIGN);
+ msg_swbd.vaddr = dma_alloc_coherent(dev, msg_swbd.size,
+ &msg_swbd.dma, GFP_KERNEL);
+ if (!msg_swbd.vaddr)
+ return -ENOMEM;
+
+ msg = (struct enetc_msg_mac_hash_filter *)msg_swbd.vaddr;
+ msg->sz_type = FIELD_PREP(ENETC_MSG_MAC_TYPE, mac_filter_type);
+ msg->sz_type |= FIELD_PREP(ENETC_MSG_MAC_HASH_SIZE,
+ ENETC_MAC_HASH_TABLE_SIZE_64);
+
+ if (mac_filter_type & ENETC_MAC_FILTER_TYPE_UC) {
+ mac_filter = &si->mac_filter[UC];
+ enetc_reset_mac_addr_filter(mac_filter);
+ netdev_hw_addr_list_for_each(ha, uc)
+ enetc_add_mac_addr_ht_filter(mac_filter, ha->addr);
+
+ bitmap_to_arr32(&msg->hash_tbl[i], mac_filter->mac_hash_table,
+ ENETC_MADDR_HASH_TBL_SZ);
+ i += 2;
+ }
+
+ if (mac_filter_type & ENETC_MAC_FILTER_TYPE_MC) {
+ mac_filter = &si->mac_filter[MC];
+ enetc_reset_mac_addr_filter(mac_filter);
+ netdev_hw_addr_list_for_each(ha, mc)
+ enetc_add_mac_addr_ht_filter(mac_filter, ha->addr);
+
+ bitmap_to_arr32(&msg->hash_tbl[i], mac_filter->mac_hash_table,
+ ENETC_MADDR_HASH_TBL_SZ);
+ }
+
+ enetc_msg_fill_common_hdr(&msg_swbd, ENETC_MSG_CLASS_ID_MAC_FILTER,
+ ENETC_MSG_SET_MAC_HASH_TABLE, 0, 0);
+
+ return enetc_msg_vsi_send(si, &msg_swbd);
+}
+
+static int enetc_vf_set_rx_mode(struct net_device *ndev,
+ struct netdev_hw_addr_list *uc,
+ struct netdev_hw_addr_list *mc)
+{
+ struct enetc_ndev_priv *priv = netdev_priv(ndev);
+ struct enetc_si *si = priv->si;
+ int err;
+
+ /* For ENETC v1, we cannot return -EOPNOTSUPP or any other error,
+ * otherwise ndev->rx_mode_retry_timer will try to set rx_mode
+ * multiple times, which is pointless.
+ */
+ if (is_enetc_rev1(si))
+ return 0;
+
+ if (ndev->flags & IFF_PROMISC) {
+ err = enetc_vf_set_mac_promisc(si, ENETC_MAC_FILTER_TYPE_ALL,
+ true);
+ } else if (ndev->flags & IFF_ALLMULTI) {
+ err = enetc_vf_set_mac_promisc(si, ENETC_MAC_FILTER_TYPE_UC,
+ false);
+ if (err)
+ goto out;
+
+ err = enetc_vf_set_mac_promisc(si, ENETC_MAC_FILTER_TYPE_MC,
+ true);
+ } else {
+ err = enetc_vf_set_mac_promisc(si, ENETC_MAC_FILTER_TYPE_ALL,
+ false);
+ }
+
+ if (err)
+ goto out;
+
+ err = enetc_vf_set_mac_hash_filter(si, uc, mc);
+
+out:
+ /* If the error code is -EOPNOTSUPP or -EACCES or -EPERM, return 0
+ * directly to avoid meaningless retries.
+ */
+ if (err == -EOPNOTSUPP || err == -EACCES || err == -EPERM)
+ return 0;
+
+ return err;
+}
+
/* Probing/ Init */
static const struct net_device_ops enetc_ndev_ops = {
.ndo_open = enetc_open,
@@ -225,6 +361,7 @@ static const struct net_device_ops enetc_ndev_ops = {
.ndo_setup_tc = enetc_vf_setup_tc,
.ndo_hwtstamp_get = enetc_hwtstamp_get,
.ndo_hwtstamp_set = enetc_hwtstamp_set,
+ .ndo_set_rx_mode_async = enetc_vf_set_rx_mode,
};
static void enetc_vf_get_revision(struct enetc_si *si)
@@ -280,6 +417,9 @@ static void enetc_vf_netdev_setup(struct enetc_si *si, struct net_device *ndev,
ndev->vlan_features = NETIF_F_SG | NETIF_F_HW_CSUM |
NETIF_F_TSO | NETIF_F_TSO6;
+ if (!is_enetc_rev1(si))
+ ndev->priv_flags |= IFF_UNICAST_FLT;
+
if (si->num_rss) {
ndev->hw_features |= NETIF_F_RXHASH;
ndev->features |= NETIF_F_RXHASH;
--
2.34.1
next prev parent reply other threads:[~2026-08-31 3:23 UTC|newest]
Thread overview: 43+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-31 2:54 [PATCH v3 net-next 00/15] net: enetc: SR-IOV improvements and ENETC v4 VF support wei.fang
2026-08-31 2:54 ` [PATCH v3 net-next 01/15] net: enetc: add trusted " wei.fang
[not found] ` <20260901032358.B913A1F00A3D@smtp.kernel.org>
2026-09-01 6:13 ` Wei Fang (OSS)
2026-09-03 23:44 ` netdev-bot+sashiko
2026-09-04 6:29 ` Wei Fang
2026-08-31 2:54 ` [PATCH v3 net-next 02/15] net: enetc: move msg_task and msg_int_name to struct enetc_si wei.fang
2026-08-31 2:54 ` [PATCH v3 net-next 03/15] net: enetc: add link status message support to PF driver wei.fang
2026-08-31 12:00 ` Andrew Lunn
2026-09-01 2:31 ` Wei Fang
2026-09-01 3:05 ` Andrew Lunn
2026-09-01 3:40 ` Wei Fang
[not found] ` <20260901032359.788A11F00A3E@smtp.kernel.org>
2026-09-01 6:46 ` Wei Fang (OSS)
2026-09-03 23:44 ` netdev-bot+sashiko
2026-09-04 7:16 ` Wei Fang
2026-08-31 2:54 ` [PATCH v3 net-next 04/15] net: enetc: add link speed " wei.fang
2026-09-03 23:44 ` netdev-bot+sashiko
2026-09-04 7:52 ` Wei Fang
2026-08-31 2:54 ` [PATCH v3 net-next 05/15] net: enetc: use enetc_set_si_hw_addr() to set VF MAC address wei.fang
2026-08-31 2:54 ` [PATCH v3 net-next 06/15] net: enetc: relocate enetc_pf_set_vf_mac() for common PF support wei.fang
2026-08-31 2:54 ` [PATCH v3 net-next 07/15] net: enetc: add .ndo_set_vf_mac() to the enetc v4 driver wei.fang
[not found] ` <20260901032358.067311F000E9@smtp.kernel.org>
2026-09-01 6:59 ` Wei Fang (OSS)
2026-08-31 2:54 ` [PATCH v3 net-next 08/15] net: enetc: move mac_filter from struct enetc_pf to struct enetc_si wei.fang
2026-08-31 2:54 ` [PATCH v3 net-next 09/15] net: enetc: add MAC address filtering support for VFs of ENETC v4 wei.fang
2026-09-03 23:44 ` netdev-bot+sashiko
2026-08-31 2:54 ` [PATCH v3 net-next 10/15] net: enetc: simplify and rename PSIIER enable/disable helpers wei.fang
2026-08-31 2:54 ` [PATCH v3 net-next 11/15] net: enetc: restore VF MAC promiscuous mode after FLR for ENETC v4 wei.fang
2026-09-03 23:44 ` netdev-bot+sashiko
2026-09-04 8:40 ` Wei Fang
2026-08-31 2:54 ` [PATCH v3 net-next 12/15] net: enetc: add VF support for i.MX94 and i.MX95 wei.fang
2026-09-03 23:44 ` netdev-bot+sashiko
2026-09-04 9:05 ` Wei Fang
2026-08-31 2:54 ` wei.fang [this message]
2026-09-03 23:44 ` [PATCH v3 net-next 13/15] net: enetc: implement ndo_set_rx_mode_async for ENETC v4 VF netdev-bot+sashiko
2026-09-04 9:53 ` Wei Fang
2026-08-31 2:54 ` [PATCH v3 net-next 14/15] net: enetc: add PSI-to-VSI link status notification support for VF wei.fang
2026-09-03 23:44 ` netdev-bot+sashiko
2026-09-04 10:47 ` Wei Fang
2026-08-31 2:54 ` [PATCH v3 net-next 15/15] net: enetc: add ndo_get_vf_config() support wei.fang
2026-09-03 23:44 ` netdev-bot+sashiko
2026-09-03 2:56 ` [PATCH v3 net-next 00/15] net: enetc: SR-IOV improvements and ENETC v4 VF support Jakub Kicinski
2026-09-03 3:24 ` Wei Fang (OSS)
2026-09-03 23:22 ` Jakub Kicinski
2026-09-04 2:02 ` Wei Fang
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=20260831025441.635045-14-wei.fang@oss.nxp.com \
--to=wei.fang@oss.nxp.com \
--cc=andrew+netdev@lunn.ch \
--cc=andrew@lunn.ch \
--cc=claudiu.manoil@nxp.com \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=imx@lists.linux.dev \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux@armlinux.org.uk \
--cc=netdev@vger.kernel.org \
--cc=olteanv@gmail.com \
--cc=pabeni@redhat.com \
--cc=vladimir.oltean@nxp.com \
--cc=wei.fang@nxp.com \
--cc=xiaoning.wang@nxp.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