* [PATCH v2 net-next 00/14] net: enetc: cleanups and improvements
@ 2026-07-02 2:57 wei.fang
2026-07-02 2:57 ` [PATCH v2 net-next 01/14] net: enetc: extract common helpers for MAC promiscuous mode setting wei.fang
` (13 more replies)
0 siblings, 14 replies; 25+ messages in thread
From: wei.fang @ 2026-07-02 2:57 UTC (permalink / raw)
To: claudiu.manoil, vladimir.oltean, xiaoning.wang, andrew+netdev,
davem, edumazet, kuba, pabeni, linux, wei.fang, chleroy
Cc: imx, netdev, linux-kernel, linuxppc-dev, linux-arm-kernel
From: Wei Fang <wei.fang@nxp.com>
The first group of patches (1, 2, 5-7) eliminates code duplication
between the ENETC v1 and v4 drivers. Since both hardware generations
share identical register layouts for MAC promiscuous mode, MAC hash
filters, and VLAN promiscuous mode - differing only in register address
offsets - common helper functions are extracted into enetc_pf_common.c
and shared by both drivers.
Patch 3 converts ndo_set_rx_mode() to ndo_set_rx_mode_async(), removing
the dedicated workqueue that was previously needed to defer MAC address
list updates to a sleepable context.
Patch 4 replaces counter-based MAFT entry tracking with a bitmap, which
keeps hardware and software state in sync and avoids partial failures
during entry allocation.
Patches 8 and 9 fix phylink-related issues: removing invalid code from
enetc4_pl_mac_link_up() and properly differentiating phylink capabilities
between pseudo-MAC and standalone MAC.
The remaining patches (10-14) are minor cleanups: removing a redundant
VLAN promiscuous mode initialization in probe, using the PCI device name
for the debugfs directory, simplifying port speed configuration, removing
a redundant num_vsi field, using alloc_etherdev_mqs() for the VF driver,
and using kzalloc_flex() for a flexible array allocation.
---
v2:
1. Modify the error log when enetc4_init_ntmp_user() fails
2. Only set PHY_INTERFACE_MODE_10GBASER and PHY_INTERFACE_MODE_XGMII for
ENETC v4, including MAC_5000FD and MAC_10000FD speeds
3. Improve the commit message of patch 13
v1 link: https://lore.kernel.org/imx/20260630072036.382761-1-wei.fang@oss.nxp.com/
---
Claudiu Manoil (1):
net: enetc: differentiate phylink capabilities for pseudo-MAC and
standalone MAC
Wei Fang (13):
net: enetc: extract common helpers for MAC promiscuous mode setting
net: enetc: extract common helpers for MAC hash filter configuration
net: enetc: convert ndo_set_rx_mode() to ndo_set_rx_mode_async()
net: enetc: improve MAFT entry management with bitmap tracking
net: enetc: use PCI device name for debugfs directory
net: enetc: simplify enetc4_set_port_speed()
net: enetc: remove invalid code from enetc4_pl_mac_link_up()
net: enetc: remove enetc4_set_default_si_vlan_promisc()
net: enetc: refactor SI VLAN promiscuous mode configuration
net: enetc: move enetc_set_si_vlan_promisc() to enetc_pf_common.c
net: enetc: remove redundant num_vsi field from enetc_port_caps
net: enetc: use alloc_etherdev_mqs() to create netdev for VF driver
net: enetc: use kzalloc_flex() for enetc_psfp_gate allocation
drivers/net/ethernet/freescale/enetc/enetc.h | 4 +-
.../ethernet/freescale/enetc/enetc4_debugfs.c | 42 +-
.../net/ethernet/freescale/enetc/enetc4_hw.h | 6 +-
.../net/ethernet/freescale/enetc/enetc4_pf.c | 412 +++++++-----------
.../ethernet/freescale/enetc/enetc_ethtool.c | 2 +-
.../net/ethernet/freescale/enetc/enetc_hw.h | 12 +-
.../net/ethernet/freescale/enetc/enetc_pf.c | 93 +---
.../net/ethernet/freescale/enetc/enetc_pf.h | 5 -
.../freescale/enetc/enetc_pf_common.c | 153 ++++++-
.../freescale/enetc/enetc_pf_common.h | 5 +
.../net/ethernet/freescale/enetc/enetc_qos.c | 4 +-
.../net/ethernet/freescale/enetc/enetc_vf.c | 3 +-
include/linux/fsl/ntmp.h | 2 +
13 files changed, 353 insertions(+), 390 deletions(-)
--
2.34.1
^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH v2 net-next 01/14] net: enetc: extract common helpers for MAC promiscuous mode setting
2026-07-02 2:57 [PATCH v2 net-next 00/14] net: enetc: cleanups and improvements wei.fang
@ 2026-07-02 2:57 ` wei.fang
2026-07-02 2:57 ` [PATCH v2 net-next 02/14] net: enetc: extract common helpers for MAC hash filter configuration wei.fang
` (12 subsequent siblings)
13 siblings, 0 replies; 25+ messages in thread
From: wei.fang @ 2026-07-02 2:57 UTC (permalink / raw)
To: claudiu.manoil, vladimir.oltean, xiaoning.wang, andrew+netdev,
davem, edumazet, kuba, pabeni, linux, wei.fang, chleroy
Cc: imx, netdev, linux-kernel, linuxppc-dev, linux-arm-kernel
From: Wei Fang <wei.fang@nxp.com>
The PSIPMMR (Port Station Interface Promiscuous MAC Mode Register) in
ENETC v4 has the same bit layout as the PSIPMR register in ENETC v1: bit
n controls unicast promiscuous mode for SI n, and bit (n + 16) controls
multicast promiscuous mode for SI n. The only difference between the two
hardware generations is the register address offset.
Since the register functionality is identical, the MAC promiscuous mode
setting code can be shared between ENETC v1 and v4 drivers.
Rename ENETC_PSIPMR to ENETC_PSIPMMR in enetc_hw.h to match the actual
register name used in the reference manual, and extract two new common
helper functions, enetc_set_si_uc_promisc() and
enetc_set_si_mc_promisc(), into enetc_pf_common.c. These helpers select
the correct register offset based on the hardware revision via
is_enetc_rev1().
Remove the v4-specific enetc4_pf_set_si_mac_promisc() function from
enetc4_pf.c and the duplicate PSIPMMR_SI_MAC_UP/MP macro definitions
from enetc4_hw.h, as they are now superseded by the shared code.
Signed-off-by: Wei Fang <wei.fang@nxp.com>
---
.../net/ethernet/freescale/enetc/enetc4_hw.h | 2 -
.../net/ethernet/freescale/enetc/enetc4_pf.c | 21 +--------
.../ethernet/freescale/enetc/enetc_ethtool.c | 2 +-
.../net/ethernet/freescale/enetc/enetc_hw.h | 7 +--
.../net/ethernet/freescale/enetc/enetc_pf.c | 11 ++---
.../freescale/enetc/enetc_pf_common.c | 44 +++++++++++++++++++
.../freescale/enetc/enetc_pf_common.h | 2 +
7 files changed, 56 insertions(+), 33 deletions(-)
diff --git a/drivers/net/ethernet/freescale/enetc/enetc4_hw.h b/drivers/net/ethernet/freescale/enetc/enetc4_hw.h
index f18437556a0e..6a8f2ed56017 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc4_hw.h
+++ b/drivers/net/ethernet/freescale/enetc/enetc4_hw.h
@@ -69,8 +69,6 @@
/* Port Station interface promiscuous MAC mode register */
#define ENETC4_PSIPMMR 0x200
-#define PSIPMMR_SI_MAC_UP(a) BIT(a) /* a = SI index */
-#define PSIPMMR_SI_MAC_MP(a) BIT((a) + 16)
/* Port Station interface promiscuous VLAN mode register */
#define ENETC4_PSIPVMR 0x204
diff --git a/drivers/net/ethernet/freescale/enetc/enetc4_pf.c b/drivers/net/ethernet/freescale/enetc/enetc4_pf.c
index 437a15bbb47b..304ec069654d 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc4_pf.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc4_pf.c
@@ -75,24 +75,6 @@ static void enetc4_pf_get_si_primary_mac(struct enetc_hw *hw, int si,
put_unaligned_le16(lower, addr + 4);
}
-static void enetc4_pf_set_si_mac_promisc(struct enetc_hw *hw, int si,
- bool uc_promisc, bool mc_promisc)
-{
- u32 val = enetc_port_rd(hw, ENETC4_PSIPMMR);
-
- if (uc_promisc)
- val |= PSIPMMR_SI_MAC_UP(si);
- else
- val &= ~PSIPMMR_SI_MAC_UP(si);
-
- if (mc_promisc)
- val |= PSIPMMR_SI_MAC_MP(si);
- else
- val &= ~PSIPMMR_SI_MAC_MP(si);
-
- enetc_port_wr(hw, ENETC4_PSIPMMR, val);
-}
-
static void enetc4_pf_set_si_uc_hash_filter(struct enetc_hw *hw, int si,
u64 hash)
{
@@ -515,7 +497,8 @@ static void enetc4_psi_do_set_rx_mode(struct work_struct *work)
type = ENETC_MAC_FILTER_TYPE_ALL;
}
- enetc4_pf_set_si_mac_promisc(hw, 0, uc_promisc, mc_promisc);
+ enetc_set_si_uc_promisc(si, 0, uc_promisc);
+ enetc_set_si_mc_promisc(si, 0, mc_promisc);
if (uc_promisc) {
enetc4_pf_set_si_uc_hash_filter(hw, 0, 0);
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_ethtool.c b/drivers/net/ethernet/freescale/enetc/enetc_ethtool.c
index 71f376ef1be1..07b7832f2427 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_ethtool.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc_ethtool.c
@@ -29,7 +29,7 @@ static const u32 enetc_rxbdr_regs[] = {
};
static const u32 enetc_port_regs[] = {
- ENETC_PMR, ENETC_PSR, ENETC_PSIPMR, ENETC_PSIPMAR0(0),
+ ENETC_PMR, ENETC_PSR, ENETC_PSIPMMR, ENETC_PSIPMAR0(0),
ENETC_PSIPMAR1(0), ENETC_PTXMBAR, ENETC_PCAPR0, ENETC_PCAPR1,
ENETC_PSICFGR0(0), ENETC_PRFSCAPR, ENETC_PTCMSDUR(0),
ENETC_PM0_CMD_CFG, ENETC_PM0_MAXFRM, ENETC_PM0_IF_MODE
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_hw.h b/drivers/net/ethernet/freescale/enetc/enetc_hw.h
index bf99b65d7598..66bfda60da9c 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_hw.h
+++ b/drivers/net/ethernet/freescale/enetc/enetc_hw.h
@@ -180,9 +180,10 @@ enum enetc_bdr_type {TX, RX};
#define ENETC_PMR_PSPEED_1000M BIT(9)
#define ENETC_PMR_PSPEED_2500M BIT(10)
#define ENETC_PSR 0x0004 /* RO */
-#define ENETC_PSIPMR 0x0018
-#define ENETC_PSIPMR_SET_UP(n) BIT(n) /* n = SI index */
-#define ENETC_PSIPMR_SET_MP(n) BIT((n) + 16)
+#define ENETC_PSIPMMR 0x0018
+#define PSIPMMR_SI_MAC_UP(n) BIT(n) /* n = SI index */
+#define PSIPMMR_SI_MAC_MP(n) BIT((n) + 16)
+
#define ENETC_PSIPVMR 0x001c
#define ENETC_VLAN_PROMISC_MAP_ALL 0x7
#define ENETC_PSIPVMR_SET_VP(simap) ((simap) & 0x7)
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pf.c b/drivers/net/ethernet/freescale/enetc/enetc_pf.c
index 2d687bb8c3a0..a97d2e2dd07b 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_pf.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.c
@@ -159,21 +159,17 @@ static void enetc_pf_set_rx_mode(struct net_device *ndev)
{
struct enetc_ndev_priv *priv = netdev_priv(ndev);
struct enetc_pf *pf = enetc_si_priv(priv->si);
- struct enetc_hw *hw = &priv->si->hw;
bool uprom = false, mprom = false;
struct enetc_mac_filter *filter;
struct netdev_hw_addr *ha;
- u32 psipmr = 0;
bool em;
if (ndev->flags & IFF_PROMISC) {
/* enable promisc mode for SI0 (PF) */
- psipmr = ENETC_PSIPMR_SET_UP(0) | ENETC_PSIPMR_SET_MP(0);
uprom = true;
mprom = true;
} else if (ndev->flags & IFF_ALLMULTI) {
/* enable multi cast promisc mode for SI0 (PF) */
- psipmr = ENETC_PSIPMR_SET_MP(0);
mprom = true;
}
@@ -211,9 +207,8 @@ static void enetc_pf_set_rx_mode(struct net_device *ndev)
/* update PF entries */
enetc_sync_mac_filters(pf);
- psipmr |= enetc_port_rd(hw, ENETC_PSIPMR) &
- ~(ENETC_PSIPMR_SET_UP(0) | ENETC_PSIPMR_SET_MP(0));
- enetc_port_wr(hw, ENETC_PSIPMR, psipmr);
+ enetc_set_si_uc_promisc(priv->si, 0, uprom);
+ enetc_set_si_mc_promisc(priv->si, 0, mprom);
}
static void enetc_set_loopback(struct net_device *ndev, bool en)
@@ -474,7 +469,7 @@ static void enetc_configure_port(struct enetc_pf *pf)
pf->vlan_promisc_simap = ENETC_VLAN_PROMISC_MAP_ALL;
enetc_set_vlan_promisc(hw, pf->vlan_promisc_simap);
- enetc_port_wr(hw, ENETC_PSIPMR, 0);
+ enetc_port_wr(hw, ENETC_PSIPMMR, 0);
/* enable port */
enetc_port_wr(hw, ENETC_PMR, ENETC_PMR_EN);
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pf_common.c b/drivers/net/ethernet/freescale/enetc/enetc_pf_common.c
index 6e5d2f869915..b0c0dc668e34 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_pf_common.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc_pf_common.c
@@ -87,6 +87,50 @@ int enetc_setup_mac_addresses(struct device_node *np, struct enetc_pf *pf)
}
EXPORT_SYMBOL_GPL(enetc_setup_mac_addresses);
+void enetc_set_si_uc_promisc(struct enetc_si *si, int si_id, bool promisc)
+{
+ struct enetc_hw *hw = &si->hw;
+ int psipmmr_off;
+ u32 val;
+
+ if (is_enetc_rev1(si))
+ psipmmr_off = ENETC_PSIPMMR;
+ else
+ psipmmr_off = ENETC4_PSIPMMR;
+
+ val = enetc_port_rd(hw, psipmmr_off);
+
+ if (promisc)
+ val |= PSIPMMR_SI_MAC_UP(si_id);
+ else
+ val &= ~PSIPMMR_SI_MAC_UP(si_id);
+
+ enetc_port_wr(hw, psipmmr_off, val);
+}
+EXPORT_SYMBOL_GPL(enetc_set_si_uc_promisc);
+
+void enetc_set_si_mc_promisc(struct enetc_si *si, int si_id, bool promisc)
+{
+ struct enetc_hw *hw = &si->hw;
+ int psipmmr_off;
+ u32 val;
+
+ if (is_enetc_rev1(si))
+ psipmmr_off = ENETC_PSIPMMR;
+ else
+ psipmmr_off = ENETC4_PSIPMMR;
+
+ val = enetc_port_rd(hw, psipmmr_off);
+
+ if (promisc)
+ val |= PSIPMMR_SI_MAC_MP(si_id);
+ else
+ val &= ~PSIPMMR_SI_MAC_MP(si_id);
+
+ enetc_port_wr(hw, psipmmr_off, val);
+}
+EXPORT_SYMBOL_GPL(enetc_set_si_mc_promisc);
+
void enetc_pf_netdev_setup(struct enetc_si *si, struct net_device *ndev,
const struct net_device_ops *ndev_ops)
{
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pf_common.h b/drivers/net/ethernet/freescale/enetc/enetc_pf_common.h
index 57d2e0ebd2b0..a619fb8fed9c 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_pf_common.h
+++ b/drivers/net/ethernet/freescale/enetc/enetc_pf_common.h
@@ -17,6 +17,8 @@ void enetc_set_default_rss_key(struct enetc_pf *pf);
int enetc_vlan_rx_add_vid(struct net_device *ndev, __be16 prot, u16 vid);
int enetc_vlan_rx_del_vid(struct net_device *ndev, __be16 prot, u16 vid);
int enetc_init_sriov_resources(struct enetc_pf *pf);
+void enetc_set_si_uc_promisc(struct enetc_si *si, int si_id, bool promisc);
+void enetc_set_si_mc_promisc(struct enetc_si *si, int si_id, bool promisc);
static inline u16 enetc_get_ip_revision(struct enetc_hw *hw)
{
--
2.34.1
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH v2 net-next 02/14] net: enetc: extract common helpers for MAC hash filter configuration
2026-07-02 2:57 [PATCH v2 net-next 00/14] net: enetc: cleanups and improvements wei.fang
2026-07-02 2:57 ` [PATCH v2 net-next 01/14] net: enetc: extract common helpers for MAC promiscuous mode setting wei.fang
@ 2026-07-02 2:57 ` wei.fang
2026-07-03 3:27 ` sashiko-bot
2026-07-02 2:57 ` [PATCH v2 net-next 03/14] net: enetc: convert ndo_set_rx_mode() to ndo_set_rx_mode_async() wei.fang
` (11 subsequent siblings)
13 siblings, 1 reply; 25+ messages in thread
From: wei.fang @ 2026-07-02 2:57 UTC (permalink / raw)
To: claudiu.manoil, vladimir.oltean, xiaoning.wang, andrew+netdev,
davem, edumazet, kuba, pabeni, linux, wei.fang, chleroy
Cc: imx, netdev, linux-kernel, linuxppc-dev, linux-arm-kernel
From: Wei Fang <wei.fang@nxp.com>
The PSIUMHFR and PSIMMHFR registers in ENETC v4 have the same bit layout
as in ENETC v1. The only difference between the two hardware generations
is the register address offsets.
Since the register functionality is identical, the MAC hash filter
configuration code can be shared between the ENETC v1 and v4 drivers.
Extract two new common helper functions, enetc_set_si_uc_hash_filter()
and enetc_set_si_mc_hash_filter(), into enetc_pf_common.c. These helpers
select the correct register offset based on the hardware revision via
is_enetc_rev1().
Remove v1-specific enetc_clear_mac_ht_flt() and enetc_set_mac_ht_flt()
from enetc_pf.c, and v4-specific enetc4_pf_set_si_uc_hash_filter() and
enetc4_pf_set_si_mc_hash_filter() from enetc4_pf.c, as they are now
superseded by the shared implementations.
Signed-off-by: Wei Fang <wei.fang@nxp.com>
---
.../net/ethernet/freescale/enetc/enetc4_pf.c | 43 +++++++---------
.../net/ethernet/freescale/enetc/enetc_pf.c | 51 +++++--------------
.../freescale/enetc/enetc_pf_common.c | 40 +++++++++++++++
.../freescale/enetc/enetc_pf_common.h | 2 +
4 files changed, 73 insertions(+), 63 deletions(-)
diff --git a/drivers/net/ethernet/freescale/enetc/enetc4_pf.c b/drivers/net/ethernet/freescale/enetc/enetc4_pf.c
index 304ec069654d..48a74db90ed5 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc4_pf.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc4_pf.c
@@ -75,20 +75,6 @@ static void enetc4_pf_get_si_primary_mac(struct enetc_hw *hw, int si,
put_unaligned_le16(lower, addr + 4);
}
-static void enetc4_pf_set_si_uc_hash_filter(struct enetc_hw *hw, int si,
- u64 hash)
-{
- enetc_port_wr(hw, ENETC4_PSIUMHFR0(si), lower_32_bits(hash));
- enetc_port_wr(hw, ENETC4_PSIUMHFR1(si), upper_32_bits(hash));
-}
-
-static void enetc4_pf_set_si_mc_hash_filter(struct enetc_hw *hw, int si,
- u64 hash)
-{
- enetc_port_wr(hw, ENETC4_PSIMMHFR0(si), lower_32_bits(hash));
- enetc_port_wr(hw, ENETC4_PSIMMHFR1(si), upper_32_bits(hash));
-}
-
static void enetc4_pf_set_loopback(struct net_device *ndev, bool en)
{
struct enetc_ndev_priv *priv = netdev_priv(ndev);
@@ -147,11 +133,12 @@ static int enetc4_pf_set_uc_exact_filter(struct enetc_pf *pf)
int max_num_mfe = pf->caps.mac_filter_num;
struct enetc_mac_filter mac_filter = {};
struct net_device *ndev = pf->si->ndev;
- struct enetc_hw *hw = &pf->si->hw;
struct enetc_mac_addr *mac_tbl;
+ struct enetc_si *si = pf->si;
struct netdev_hw_addr *ha;
int i = 0, err;
int mac_cnt;
+ u64 hash;
netif_addr_lock_bh(ndev);
@@ -159,7 +146,7 @@ static int enetc4_pf_set_uc_exact_filter(struct enetc_pf *pf)
if (!mac_cnt) {
netif_addr_unlock_bh(ndev);
/* clear both MAC hash and exact filters */
- enetc4_pf_set_si_uc_hash_filter(hw, 0, 0);
+ enetc_set_si_uc_hash_filter(si, 0, 0);
enetc4_pf_clear_maft_entries(pf);
return 0;
@@ -186,11 +173,13 @@ static int enetc4_pf_set_uc_exact_filter(struct enetc_pf *pf)
/* Set temporary unicast hash filters in case of Rx loss when
* updating MAC address filter table
*/
- enetc4_pf_set_si_uc_hash_filter(hw, 0, *mac_filter.mac_hash_table);
+ bitmap_to_arr64(&hash, mac_filter.mac_hash_table,
+ ENETC_MADDR_HASH_TBL_SZ);
+ enetc_set_si_uc_hash_filter(si, 0, hash);
enetc4_pf_clear_maft_entries(pf);
if (!enetc4_pf_add_maft_entries(pf, mac_tbl, i))
- enetc4_pf_set_si_uc_hash_filter(hw, 0, 0);
+ enetc_set_si_uc_hash_filter(si, 0, 0);
kfree(mac_tbl);
@@ -206,8 +195,9 @@ static void enetc4_pf_set_mac_hash_filter(struct enetc_pf *pf, int type)
{
struct net_device *ndev = pf->si->ndev;
struct enetc_mac_filter *mac_filter;
- struct enetc_hw *hw = &pf->si->hw;
+ struct enetc_si *si = pf->si;
struct netdev_hw_addr *ha;
+ u64 hash;
netif_addr_lock_bh(ndev);
if (type & ENETC_MAC_FILTER_TYPE_UC) {
@@ -216,8 +206,9 @@ static void enetc4_pf_set_mac_hash_filter(struct enetc_pf *pf, int type)
netdev_for_each_uc_addr(ha, ndev)
enetc_add_mac_addr_ht_filter(mac_filter, ha->addr);
- enetc4_pf_set_si_uc_hash_filter(hw, 0,
- *mac_filter->mac_hash_table);
+ bitmap_to_arr64(&hash, mac_filter->mac_hash_table,
+ ENETC_MADDR_HASH_TBL_SZ);
+ enetc_set_si_uc_hash_filter(si, 0, hash);
}
if (type & ENETC_MAC_FILTER_TYPE_MC) {
@@ -226,8 +217,9 @@ static void enetc4_pf_set_mac_hash_filter(struct enetc_pf *pf, int type)
netdev_for_each_mc_addr(ha, ndev)
enetc_add_mac_addr_ht_filter(mac_filter, ha->addr);
- enetc4_pf_set_si_mc_hash_filter(hw, 0,
- *mac_filter->mac_hash_table);
+ bitmap_to_arr64(&hash, mac_filter->mac_hash_table,
+ ENETC_MADDR_HASH_TBL_SZ);
+ enetc_set_si_mc_hash_filter(si, 0, hash);
}
netif_addr_unlock_bh(ndev);
}
@@ -480,7 +472,6 @@ static void enetc4_psi_do_set_rx_mode(struct work_struct *work)
struct enetc_si *si = container_of(work, struct enetc_si, rx_mode_task);
struct enetc_pf *pf = enetc_si_priv(si);
struct net_device *ndev = si->ndev;
- struct enetc_hw *hw = &si->hw;
bool uc_promisc = false;
bool mc_promisc = false;
int type = 0;
@@ -501,12 +492,12 @@ static void enetc4_psi_do_set_rx_mode(struct work_struct *work)
enetc_set_si_mc_promisc(si, 0, mc_promisc);
if (uc_promisc) {
- enetc4_pf_set_si_uc_hash_filter(hw, 0, 0);
+ enetc_set_si_uc_hash_filter(si, 0, 0);
enetc4_pf_clear_maft_entries(pf);
}
if (mc_promisc)
- enetc4_pf_set_si_mc_hash_filter(hw, 0, 0);
+ enetc_set_si_mc_hash_filter(si, 0, 0);
/* Set new MAC filter */
enetc4_pf_set_mac_filter(pf, type);
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pf.c b/drivers/net/ethernet/freescale/enetc/enetc_pf.c
index a97d2e2dd07b..db2a800a7aaf 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_pf.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.c
@@ -80,37 +80,6 @@ static void enetc_add_mac_addr_em_filter(struct enetc_mac_filter *filter,
filter->mac_addr_cnt++;
}
-static void enetc_clear_mac_ht_flt(struct enetc_si *si, int si_idx, int type)
-{
- bool err = si->errata & ENETC_ERR_UCMCSWP;
-
- if (type == UC) {
- enetc_port_wr(&si->hw, ENETC_PSIUMHFR0(si_idx, err), 0);
- enetc_port_wr(&si->hw, ENETC_PSIUMHFR1(si_idx), 0);
- } else { /* MC */
- enetc_port_wr(&si->hw, ENETC_PSIMMHFR0(si_idx, err), 0);
- enetc_port_wr(&si->hw, ENETC_PSIMMHFR1(si_idx), 0);
- }
-}
-
-static void enetc_set_mac_ht_flt(struct enetc_si *si, int si_idx, int type,
- unsigned long hash)
-{
- bool err = si->errata & ENETC_ERR_UCMCSWP;
-
- if (type == UC) {
- enetc_port_wr(&si->hw, ENETC_PSIUMHFR0(si_idx, err),
- lower_32_bits(hash));
- enetc_port_wr(&si->hw, ENETC_PSIUMHFR1(si_idx),
- upper_32_bits(hash));
- } else { /* MC */
- enetc_port_wr(&si->hw, ENETC_PSIMMHFR0(si_idx, err),
- lower_32_bits(hash));
- enetc_port_wr(&si->hw, ENETC_PSIMMHFR1(si_idx),
- upper_32_bits(hash));
- }
-}
-
static void enetc_sync_mac_filters(struct enetc_pf *pf)
{
struct enetc_mac_filter *f = pf->mac_filter;
@@ -122,12 +91,16 @@ static void enetc_sync_mac_filters(struct enetc_pf *pf)
for (i = 0; i < MADDR_TYPE; i++, f++) {
bool em = (f->mac_addr_cnt == 1) && (i == UC);
bool clear = !f->mac_addr_cnt;
+ u64 hash;
if (clear) {
- if (i == UC)
+ if (i == UC) {
enetc_clear_mac_flt_entry(si, pos);
+ enetc_set_si_uc_hash_filter(si, 0, 0);
+ } else {
+ enetc_set_si_mc_hash_filter(si, 0, 0);
+ }
- enetc_clear_mac_ht_flt(si, 0, i);
continue;
}
@@ -135,7 +108,7 @@ static void enetc_sync_mac_filters(struct enetc_pf *pf)
if (em) {
int err;
- enetc_clear_mac_ht_flt(si, 0, UC);
+ enetc_set_si_uc_hash_filter(si, 0, 0);
err = enetc_set_mac_flt_entry(si, pos, f->mac_addr,
BIT(0));
@@ -147,11 +120,15 @@ static void enetc_sync_mac_filters(struct enetc_pf *pf)
err);
}
+ bitmap_to_arr64(&hash, f->mac_hash_table,
+ ENETC_MADDR_HASH_TBL_SZ);
/* hash table filter, clear EM filter for UC entries */
- if (i == UC)
+ if (i == UC) {
enetc_clear_mac_flt_entry(si, pos);
-
- enetc_set_mac_ht_flt(si, 0, i, *f->mac_hash_table);
+ enetc_set_si_uc_hash_filter(si, 0, hash);
+ } else {
+ enetc_set_si_mc_hash_filter(si, 0, hash);
+ }
}
}
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pf_common.c b/drivers/net/ethernet/freescale/enetc/enetc_pf_common.c
index b0c0dc668e34..3597cb81a7cc 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_pf_common.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc_pf_common.c
@@ -131,6 +131,46 @@ void enetc_set_si_mc_promisc(struct enetc_si *si, int si_id, bool promisc)
}
EXPORT_SYMBOL_GPL(enetc_set_si_mc_promisc);
+void enetc_set_si_uc_hash_filter(struct enetc_si *si, int si_id, u64 hash)
+{
+ int psiumhfr0_off, psiumhfr1_off;
+ struct enetc_hw *hw = &si->hw;
+
+ if (is_enetc_rev1(si)) {
+ bool err = si->errata & ENETC_ERR_UCMCSWP;
+
+ psiumhfr0_off = ENETC_PSIUMHFR0(si_id, err);
+ psiumhfr1_off = ENETC_PSIUMHFR1(si_id);
+ } else {
+ psiumhfr0_off = ENETC4_PSIUMHFR0(si_id);
+ psiumhfr1_off = ENETC4_PSIUMHFR1(si_id);
+ }
+
+ enetc_port_wr(hw, psiumhfr0_off, lower_32_bits(hash));
+ enetc_port_wr(hw, psiumhfr1_off, upper_32_bits(hash));
+}
+EXPORT_SYMBOL_GPL(enetc_set_si_uc_hash_filter);
+
+void enetc_set_si_mc_hash_filter(struct enetc_si *si, int si_id, u64 hash)
+{
+ int psimmhfr0_off, psimmhfr1_off;
+ struct enetc_hw *hw = &si->hw;
+
+ if (is_enetc_rev1(si)) {
+ bool err = si->errata & ENETC_ERR_UCMCSWP;
+
+ psimmhfr0_off = ENETC_PSIMMHFR0(si_id, err);
+ psimmhfr1_off = ENETC_PSIMMHFR1(si_id);
+ } else {
+ psimmhfr0_off = ENETC4_PSIMMHFR0(si_id);
+ psimmhfr1_off = ENETC4_PSIMMHFR1(si_id);
+ }
+
+ enetc_port_wr(hw, psimmhfr0_off, lower_32_bits(hash));
+ enetc_port_wr(hw, psimmhfr1_off, upper_32_bits(hash));
+}
+EXPORT_SYMBOL_GPL(enetc_set_si_mc_hash_filter);
+
void enetc_pf_netdev_setup(struct enetc_si *si, struct net_device *ndev,
const struct net_device_ops *ndev_ops)
{
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pf_common.h b/drivers/net/ethernet/freescale/enetc/enetc_pf_common.h
index a619fb8fed9c..bf9029b0a017 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_pf_common.h
+++ b/drivers/net/ethernet/freescale/enetc/enetc_pf_common.h
@@ -19,6 +19,8 @@ int enetc_vlan_rx_del_vid(struct net_device *ndev, __be16 prot, u16 vid);
int enetc_init_sriov_resources(struct enetc_pf *pf);
void enetc_set_si_uc_promisc(struct enetc_si *si, int si_id, bool promisc);
void enetc_set_si_mc_promisc(struct enetc_si *si, int si_id, bool promisc);
+void enetc_set_si_uc_hash_filter(struct enetc_si *si, int si_id, u64 hash);
+void enetc_set_si_mc_hash_filter(struct enetc_si *si, int si_id, u64 hash);
static inline u16 enetc_get_ip_revision(struct enetc_hw *hw)
{
--
2.34.1
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH v2 net-next 03/14] net: enetc: convert ndo_set_rx_mode() to ndo_set_rx_mode_async()
2026-07-02 2:57 [PATCH v2 net-next 00/14] net: enetc: cleanups and improvements wei.fang
2026-07-02 2:57 ` [PATCH v2 net-next 01/14] net: enetc: extract common helpers for MAC promiscuous mode setting wei.fang
2026-07-02 2:57 ` [PATCH v2 net-next 02/14] net: enetc: extract common helpers for MAC hash filter configuration wei.fang
@ 2026-07-02 2:57 ` wei.fang
2026-07-02 2:57 ` [PATCH v2 net-next 04/14] net: enetc: improve MAFT entry management with bitmap tracking wei.fang
` (10 subsequent siblings)
13 siblings, 0 replies; 25+ messages in thread
From: wei.fang @ 2026-07-02 2:57 UTC (permalink / raw)
To: claudiu.manoil, vladimir.oltean, xiaoning.wang, andrew+netdev,
davem, edumazet, kuba, pabeni, linux, wei.fang, chleroy
Cc: imx, netdev, linux-kernel, linuxppc-dev, linux-arm-kernel
From: Wei Fang <wei.fang@nxp.com>
The current ndo_set_rx_mode() is called under netif_addr_lock spinlock
with BHs disabled, which prevents drivers from sleeping. To work around
this limitation, the enetc driver uses a dedicated workqueue to defer
MAC address list updates to a sleepable context.
Since commit 3554b4345d85 ("net: introduce ndo_set_rx_mode_async and
netdev_rx_mode_work") introduced the ndo_set_rx_mode_async() callback,
drivers can now handle address list updates directly in a sleepable
context.
Therefore, convert the enetc driver to use ndo_set_rx_mode_async() and
remove the dedicated workqueue and the deferred work item accordingly.
Signed-off-by: Wei Fang <wei.fang@nxp.com>
---
drivers/net/ethernet/freescale/enetc/enetc.h | 2 -
.../net/ethernet/freescale/enetc/enetc4_pf.c | 178 ++++++------------
2 files changed, 58 insertions(+), 122 deletions(-)
diff --git a/drivers/net/ethernet/freescale/enetc/enetc.h b/drivers/net/ethernet/freescale/enetc/enetc.h
index 04a5dd5ea6c7..06a9f1ee0970 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc.h
+++ b/drivers/net/ethernet/freescale/enetc/enetc.h
@@ -324,8 +324,6 @@ struct enetc_si {
const struct enetc_drvdata *drvdata;
const struct enetc_si_ops *ops;
- struct workqueue_struct *workqueue;
- struct work_struct rx_mode_task;
struct dentry *debugfs_root;
struct enetc_msg_swbd msg; /* Only valid for VSI */
};
diff --git a/drivers/net/ethernet/freescale/enetc/enetc4_pf.c b/drivers/net/ethernet/freescale/enetc/enetc4_pf.c
index 48a74db90ed5..a02b01753ff2 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc4_pf.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc4_pf.c
@@ -101,24 +101,23 @@ static void enetc4_pf_clear_maft_entries(struct enetc_pf *pf)
}
static int enetc4_pf_add_maft_entries(struct enetc_pf *pf,
- struct enetc_mac_addr *mac,
- int mac_cnt)
+ struct netdev_hw_addr_list *uc)
{
struct maft_entry_data maft = {};
+ struct netdev_hw_addr *ha;
u16 si_bit = BIT(0);
- int i, err;
+ int err;
maft.cfge.si_bitmap = cpu_to_le16(si_bit);
- for (i = 0; i < mac_cnt; i++) {
- ether_addr_copy(maft.keye.mac_addr, mac[i].addr);
- err = ntmp_maft_add_entry(&pf->si->ntmp_user, i, &maft);
- if (unlikely(err)) {
- pf->num_mfe = i;
+ netdev_hw_addr_list_for_each(ha, uc) {
+ ether_addr_copy(maft.keye.mac_addr, ha->addr);
+ err = ntmp_maft_add_entry(&pf->si->ntmp_user, pf->num_mfe,
+ &maft);
+ if (unlikely(err))
goto clear_maft_entries;
- }
- }
- pf->num_mfe = mac_cnt;
+ pf->num_mfe++;
+ }
return 0;
@@ -128,23 +127,29 @@ static int enetc4_pf_add_maft_entries(struct enetc_pf *pf,
return err;
}
-static int enetc4_pf_set_uc_exact_filter(struct enetc_pf *pf)
+static void enetc4_pf_set_uc_hash_filter(struct enetc_pf *pf,
+ struct netdev_hw_addr_list *uc)
{
- int max_num_mfe = pf->caps.mac_filter_num;
- struct enetc_mac_filter mac_filter = {};
- struct net_device *ndev = pf->si->ndev;
- struct enetc_mac_addr *mac_tbl;
- struct enetc_si *si = pf->si;
+ struct enetc_mac_filter *mac_filter = &pf->mac_filter[UC];
struct netdev_hw_addr *ha;
- int i = 0, err;
- int mac_cnt;
u64 hash;
- netif_addr_lock_bh(ndev);
+ 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_arr64(&hash, mac_filter->mac_hash_table,
+ ENETC_MADDR_HASH_TBL_SZ);
+ enetc_set_si_uc_hash_filter(pf->si, 0, hash);
+}
+
+static int enetc4_pf_set_uc_exact_filter(struct enetc_pf *pf,
+ struct netdev_hw_addr_list *uc)
+{
+ int mac_cnt = netdev_hw_addr_list_count(uc);
+ struct enetc_si *si = pf->si;
- mac_cnt = netdev_uc_count(ndev);
if (!mac_cnt) {
- netif_addr_unlock_bh(ndev);
/* clear both MAC hash and exact filters */
enetc_set_si_uc_hash_filter(si, 0, 0);
enetc4_pf_clear_maft_entries(pf);
@@ -152,79 +157,42 @@ static int enetc4_pf_set_uc_exact_filter(struct enetc_pf *pf)
return 0;
}
- if (mac_cnt > max_num_mfe) {
- err = -ENOSPC;
- goto unlock_netif_addr;
- }
-
- mac_tbl = kzalloc_objs(*mac_tbl, mac_cnt, GFP_ATOMIC);
- if (!mac_tbl) {
- err = -ENOMEM;
- goto unlock_netif_addr;
- }
-
- netdev_for_each_uc_addr(ha, ndev) {
- enetc_add_mac_addr_ht_filter(&mac_filter, ha->addr);
- ether_addr_copy(mac_tbl[i++].addr, ha->addr);
- }
-
- netif_addr_unlock_bh(ndev);
+ if (mac_cnt > pf->caps.mac_filter_num)
+ return -ENOSPC;
/* Set temporary unicast hash filters in case of Rx loss when
* updating MAC address filter table
*/
- bitmap_to_arr64(&hash, mac_filter.mac_hash_table,
- ENETC_MADDR_HASH_TBL_SZ);
- enetc_set_si_uc_hash_filter(si, 0, hash);
+ enetc4_pf_set_uc_hash_filter(pf, uc);
enetc4_pf_clear_maft_entries(pf);
- if (!enetc4_pf_add_maft_entries(pf, mac_tbl, i))
+ if (!enetc4_pf_add_maft_entries(pf, uc)) {
+ enetc_reset_mac_addr_filter(&pf->mac_filter[UC]);
enetc_set_si_uc_hash_filter(si, 0, 0);
-
- kfree(mac_tbl);
+ }
return 0;
-
-unlock_netif_addr:
- netif_addr_unlock_bh(ndev);
-
- return err;
}
-static void enetc4_pf_set_mac_hash_filter(struct enetc_pf *pf, int type)
+static void enetc4_pf_set_mc_hash_filter(struct enetc_pf *pf,
+ struct netdev_hw_addr_list *mc)
{
- struct net_device *ndev = pf->si->ndev;
- struct enetc_mac_filter *mac_filter;
- struct enetc_si *si = pf->si;
+ struct enetc_mac_filter *mac_filter = &pf->mac_filter[MC];
struct netdev_hw_addr *ha;
u64 hash;
- netif_addr_lock_bh(ndev);
- if (type & ENETC_MAC_FILTER_TYPE_UC) {
- mac_filter = &pf->mac_filter[UC];
- enetc_reset_mac_addr_filter(mac_filter);
- netdev_for_each_uc_addr(ha, ndev)
- enetc_add_mac_addr_ht_filter(mac_filter, ha->addr);
-
- bitmap_to_arr64(&hash, mac_filter->mac_hash_table,
- ENETC_MADDR_HASH_TBL_SZ);
- enetc_set_si_uc_hash_filter(si, 0, hash);
- }
+ 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);
- if (type & ENETC_MAC_FILTER_TYPE_MC) {
- mac_filter = &pf->mac_filter[MC];
- enetc_reset_mac_addr_filter(mac_filter);
- netdev_for_each_mc_addr(ha, ndev)
- enetc_add_mac_addr_ht_filter(mac_filter, ha->addr);
-
- bitmap_to_arr64(&hash, mac_filter->mac_hash_table,
- ENETC_MADDR_HASH_TBL_SZ);
- enetc_set_si_mc_hash_filter(si, 0, hash);
- }
- netif_addr_unlock_bh(ndev);
+ bitmap_to_arr64(&hash, mac_filter->mac_hash_table,
+ ENETC_MADDR_HASH_TBL_SZ);
+ enetc_set_si_mc_hash_filter(pf->si, 0, hash);
}
-static void enetc4_pf_set_mac_filter(struct enetc_pf *pf, int type)
+static void enetc4_pf_set_mac_filter(struct enetc_pf *pf, int type,
+ struct netdev_hw_addr_list *uc,
+ struct netdev_hw_addr_list *mc)
{
/* Currently, the MAC address filter table (MAFT) only has 4 entries,
* and multiple multicast addresses for filtering will be configured
@@ -232,15 +200,16 @@ static void enetc4_pf_set_mac_filter(struct enetc_pf *pf, int type)
* unicast filtering. If the number of unicast addresses exceeds the
* table capacity, the MAC hash filter will be used.
*/
- if (type & ENETC_MAC_FILTER_TYPE_UC && enetc4_pf_set_uc_exact_filter(pf)) {
+ if (type & ENETC_MAC_FILTER_TYPE_UC &&
+ enetc4_pf_set_uc_exact_filter(pf, uc)) {
/* Fall back to the MAC hash filter */
- enetc4_pf_set_mac_hash_filter(pf, ENETC_MAC_FILTER_TYPE_UC);
+ enetc4_pf_set_uc_hash_filter(pf, uc);
/* Clear the old MAC exact filter */
enetc4_pf_clear_maft_entries(pf);
}
if (type & ENETC_MAC_FILTER_TYPE_MC)
- enetc4_pf_set_mac_hash_filter(pf, ENETC_MAC_FILTER_TYPE_MC);
+ enetc4_pf_set_mc_hash_filter(pf, mc);
}
static const struct enetc_pf_ops enetc4_pf_ops = {
@@ -467,17 +436,17 @@ static void enetc4_pf_free(struct enetc_pf *pf)
enetc4_free_ntmp_user(pf->si);
}
-static void enetc4_psi_do_set_rx_mode(struct work_struct *work)
+static int enetc4_pf_set_rx_mode(struct net_device *ndev,
+ struct netdev_hw_addr_list *uc,
+ struct netdev_hw_addr_list *mc)
{
- struct enetc_si *si = container_of(work, struct enetc_si, rx_mode_task);
- struct enetc_pf *pf = enetc_si_priv(si);
- struct net_device *ndev = si->ndev;
+ struct enetc_ndev_priv *priv = netdev_priv(ndev);
+ struct enetc_pf *pf = enetc_si_priv(priv->si);
+ struct enetc_si *si = priv->si;
bool uc_promisc = false;
bool mc_promisc = false;
int type = 0;
- rtnl_lock();
-
if (ndev->flags & IFF_PROMISC) {
uc_promisc = true;
mc_promisc = true;
@@ -500,17 +469,9 @@ static void enetc4_psi_do_set_rx_mode(struct work_struct *work)
enetc_set_si_mc_hash_filter(si, 0, 0);
/* Set new MAC filter */
- enetc4_pf_set_mac_filter(pf, type);
-
- rtnl_unlock();
-}
+ enetc4_pf_set_mac_filter(pf, type, uc, mc);
-static void enetc4_pf_set_rx_mode(struct net_device *ndev)
-{
- struct enetc_ndev_priv *priv = netdev_priv(ndev);
- struct enetc_si *si = priv->si;
-
- queue_work(si->workqueue, &si->rx_mode_task);
+ return 0;
}
static int enetc4_pf_set_features(struct net_device *ndev,
@@ -540,7 +501,7 @@ static const struct net_device_ops enetc4_ndev_ops = {
.ndo_start_xmit = enetc_xmit,
.ndo_get_stats = enetc_get_stats,
.ndo_set_mac_address = enetc_pf_set_mac_addr,
- .ndo_set_rx_mode = enetc4_pf_set_rx_mode,
+ .ndo_set_rx_mode_async = enetc4_pf_set_rx_mode,
.ndo_set_features = enetc4_pf_set_features,
.ndo_vlan_rx_add_vid = enetc_vlan_rx_add_vid,
.ndo_vlan_rx_kill_vid = enetc_vlan_rx_del_vid,
@@ -983,19 +944,6 @@ static void enetc4_link_deinit(struct enetc_ndev_priv *priv)
enetc_mdiobus_destroy(pf);
}
-static int enetc4_psi_wq_task_init(struct enetc_si *si)
-{
- char wq_name[24];
-
- INIT_WORK(&si->rx_mode_task, enetc4_psi_do_set_rx_mode);
- snprintf(wq_name, sizeof(wq_name), "enetc-%s", pci_name(si->pdev));
- si->workqueue = create_singlethread_workqueue(wq_name);
- if (!si->workqueue)
- return -ENOMEM;
-
- return 0;
-}
-
static int enetc4_pf_netdev_create(struct enetc_si *si)
{
struct device *dev = &si->pdev->dev;
@@ -1036,12 +984,6 @@ static int enetc4_pf_netdev_create(struct enetc_si *si)
if (err)
goto err_link_init;
- err = enetc4_psi_wq_task_init(si);
- if (err) {
- dev_err(dev, "Failed to init workqueue\n");
- goto err_wq_init;
- }
-
err = register_netdev(ndev);
if (err) {
dev_err(dev, "Failed to register netdev\n");
@@ -1051,8 +993,6 @@ static int enetc4_pf_netdev_create(struct enetc_si *si)
return 0;
err_reg_netdev:
- destroy_workqueue(si->workqueue);
-err_wq_init:
enetc4_link_deinit(priv);
err_link_init:
enetc_free_msix(priv);
@@ -1070,8 +1010,6 @@ static void enetc4_pf_netdev_destroy(struct enetc_si *si)
struct net_device *ndev = si->ndev;
unregister_netdev(ndev);
- cancel_work(&si->rx_mode_task);
- destroy_workqueue(si->workqueue);
enetc4_link_deinit(priv);
enetc_free_msix(priv);
free_netdev(ndev);
--
2.34.1
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH v2 net-next 04/14] net: enetc: improve MAFT entry management with bitmap tracking
2026-07-02 2:57 [PATCH v2 net-next 00/14] net: enetc: cleanups and improvements wei.fang
` (2 preceding siblings ...)
2026-07-02 2:57 ` [PATCH v2 net-next 03/14] net: enetc: convert ndo_set_rx_mode() to ndo_set_rx_mode_async() wei.fang
@ 2026-07-02 2:57 ` wei.fang
2026-07-02 2:57 ` [PATCH v2 net-next 05/14] net: enetc: use PCI device name for debugfs directory wei.fang
` (9 subsequent siblings)
13 siblings, 0 replies; 25+ messages in thread
From: wei.fang @ 2026-07-02 2:57 UTC (permalink / raw)
To: claudiu.manoil, vladimir.oltean, xiaoning.wang, andrew+netdev,
davem, edumazet, kuba, pabeni, linux, wei.fang, chleroy
Cc: imx, netdev, linux-kernel, linuxppc-dev, linux-arm-kernel
From: Wei Fang <wei.fang@nxp.com>
Replace the counter-based MAFT entry tracking (num_mfe/mac_filter_num)
with a bitmap (maft_eid_bitmap) stored in struct ntmp_user, which is a
more appropriate place for NTMP resource management.
The bitmap approach brings two improvements. First, the entry deletion
in enetc4_pf_clear_maft_entries() now checks the return value of
ntmp_maft_delete_entry() and only clears the corresponding bit on
success, keeping hardware and software state in sync. Previously, the
counter was reset unconditionally regardless of whether the hardware
deletion actually succeeded.
Second, entry allocation in enetc4_pf_add_maft_entries() uses
ntmp_lookup_free_eid() to find available IDs dynamically, with an
upfront capacity check via bitmap_weight() to avoid partial failures.
The MAFT entry count is moved into ntmp_user.maft_num_entries and
initialized once during enetc4_init_ntmp_user(). Helper functions
enetc4_ntmp_bitmap_init() and enetc4_ntmp_bitmap_free() manage the
bitmap lifetime. The debugfs show function is updated accordingly to
iterate over set bits under rtnl_lock().
Signed-off-by: Wei Fang <wei.fang@nxp.com>
---
.../ethernet/freescale/enetc/enetc4_debugfs.c | 30 ++++--
.../net/ethernet/freescale/enetc/enetc4_pf.c | 97 ++++++++++++++-----
.../net/ethernet/freescale/enetc/enetc_pf.h | 3 -
include/linux/fsl/ntmp.h | 2 +
4 files changed, 96 insertions(+), 36 deletions(-)
diff --git a/drivers/net/ethernet/freescale/enetc/enetc4_debugfs.c b/drivers/net/ethernet/freescale/enetc/enetc4_debugfs.c
index 1b1591dce73d..4a769d9e5679 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc4_debugfs.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc4_debugfs.c
@@ -31,9 +31,11 @@ static int enetc_mac_filter_show(struct seq_file *s, void *data)
struct enetc_si *si = s->private;
struct enetc_hw *hw = &si->hw;
struct maft_entry_data maft;
+ struct ntmp_user *user;
struct enetc_pf *pf;
- int i, err, num_si;
- u32 val;
+ u32 val, entry_id;
+ int i, num_si;
+ int err = 0;
pf = enetc_si_priv(si);
num_si = pf->caps.num_vsi + 1;
@@ -50,22 +52,30 @@ static int enetc_mac_filter_show(struct seq_file *s, void *data)
for (i = 0; i < num_si; i++)
enetc_show_si_mac_hash_filter(s, i);
- if (!pf->num_mfe)
- return 0;
+ user = &si->ntmp_user;
+ rtnl_lock();
+
+ if (bitmap_empty(user->maft_eid_bitmap, user->maft_num_entries))
+ goto unlock_rtnl;
/* MAC address filter table */
seq_puts(s, "MAC address filter table\n");
- for (i = 0; i < pf->num_mfe; i++) {
+ for_each_set_bit(entry_id, user->maft_eid_bitmap,
+ user->maft_num_entries) {
memset(&maft, 0, sizeof(maft));
- err = ntmp_maft_query_entry(&si->ntmp_user, i, &maft);
+ err = ntmp_maft_query_entry(user, entry_id, &maft);
if (err)
- return err;
+ goto unlock_rtnl;
- seq_printf(s, "Entry %d, MAC: %pM, SI bitmap: 0x%04x\n", i,
- maft.keye.mac_addr, le16_to_cpu(maft.cfge.si_bitmap));
+ seq_printf(s, "Entry %d, MAC: %pM, SI bitmap: 0x%04x\n",
+ entry_id, maft.keye.mac_addr,
+ le16_to_cpu(maft.cfge.si_bitmap));
}
- return 0;
+unlock_rtnl:
+ rtnl_unlock();
+
+ return err;
}
DEFINE_SHOW_ATTRIBUTE(enetc_mac_filter);
diff --git a/drivers/net/ethernet/freescale/enetc/enetc4_pf.c b/drivers/net/ethernet/freescale/enetc/enetc4_pf.c
index a02b01753ff2..b966637572a7 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc4_pf.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc4_pf.c
@@ -32,9 +32,6 @@ static void enetc4_get_port_caps(struct enetc_pf *pf)
val = enetc_port_rd(hw, ENETC4_PMCAPR);
pf->caps.half_duplex = (val & PMCAPR_HD) ? 1 : 0;
-
- val = enetc_port_rd(hw, ENETC4_PSIMAFCAPR);
- pf->caps.mac_filter_num = val & PSIMAFCAPR_NUM_MAC_AFTE;
}
static void enetc4_get_psi_hw_features(struct enetc_si *si)
@@ -92,31 +89,45 @@ static void enetc4_pf_set_loopback(struct net_device *ndev, bool en)
static void enetc4_pf_clear_maft_entries(struct enetc_pf *pf)
{
- int i;
+ struct ntmp_user *user = &pf->si->ntmp_user;
+ u32 entry_id;
- for (i = 0; i < pf->num_mfe; i++)
- ntmp_maft_delete_entry(&pf->si->ntmp_user, i);
-
- pf->num_mfe = 0;
+ for_each_set_bit(entry_id, user->maft_eid_bitmap,
+ user->maft_num_entries) {
+ if (!ntmp_maft_delete_entry(user, entry_id))
+ ntmp_clear_eid_bitmap(user->maft_eid_bitmap, entry_id);
+ }
}
static int enetc4_pf_add_maft_entries(struct enetc_pf *pf,
struct netdev_hw_addr_list *uc)
{
+ struct ntmp_user *user = &pf->si->ntmp_user;
+ int mac_cnt = netdev_hw_addr_list_count(uc);
struct maft_entry_data maft = {};
struct netdev_hw_addr *ha;
+ u32 available_entries;
u16 si_bit = BIT(0);
+ u32 entry_id;
int err;
+ available_entries = user->maft_num_entries -
+ bitmap_weight(user->maft_eid_bitmap,
+ user->maft_num_entries);
+
+ if (mac_cnt > available_entries)
+ return -ENOSPC;
+
maft.cfge.si_bitmap = cpu_to_le16(si_bit);
netdev_hw_addr_list_for_each(ha, uc) {
+ entry_id = ntmp_lookup_free_eid(user->maft_eid_bitmap,
+ user->maft_num_entries);
ether_addr_copy(maft.keye.mac_addr, ha->addr);
- err = ntmp_maft_add_entry(&pf->si->ntmp_user, pf->num_mfe,
- &maft);
- if (unlikely(err))
+ err = ntmp_maft_add_entry(user, entry_id, &maft);
+ if (unlikely(err)) {
+ ntmp_clear_eid_bitmap(user->maft_eid_bitmap, entry_id);
goto clear_maft_entries;
-
- pf->num_mfe++;
+ }
}
return 0;
@@ -146,10 +157,10 @@ static void enetc4_pf_set_uc_hash_filter(struct enetc_pf *pf,
static int enetc4_pf_set_uc_exact_filter(struct enetc_pf *pf,
struct netdev_hw_addr_list *uc)
{
- int mac_cnt = netdev_hw_addr_list_count(uc);
struct enetc_si *si = pf->si;
+ int err;
- if (!mac_cnt) {
+ if (netdev_hw_addr_list_empty(uc)) {
/* clear both MAC hash and exact filters */
enetc_set_si_uc_hash_filter(si, 0, 0);
enetc4_pf_clear_maft_entries(pf);
@@ -157,21 +168,19 @@ static int enetc4_pf_set_uc_exact_filter(struct enetc_pf *pf,
return 0;
}
- if (mac_cnt > pf->caps.mac_filter_num)
- return -ENOSPC;
-
- /* Set temporary unicast hash filters in case of Rx loss when
+ /* Set temporary unicast hash filter in case of Rx loss when
* updating MAC address filter table
*/
enetc4_pf_set_uc_hash_filter(pf, uc);
enetc4_pf_clear_maft_entries(pf);
- if (!enetc4_pf_add_maft_entries(pf, uc)) {
+ err = enetc4_pf_add_maft_entries(pf, uc);
+ if (!err) {
enetc_reset_mac_addr_filter(&pf->mac_filter[UC]);
enetc_set_si_uc_hash_filter(si, 0, 0);
}
- return 0;
+ return err;
}
static void enetc4_pf_set_mc_hash_filter(struct enetc_pf *pf,
@@ -393,18 +402,60 @@ static void enetc4_configure_port(struct enetc_pf *pf)
enetc_set_default_rss_key(pf);
}
+static void enetc4_get_ntmp_caps(struct enetc_si *si)
+{
+ struct ntmp_user *user = &si->ntmp_user;
+ struct enetc_hw *hw = &si->hw;
+ u32 val;
+
+ val = enetc_port_rd(hw, ENETC4_PSIMAFCAPR);
+ user->maft_num_entries = FIELD_GET(PSIMAFCAPR_NUM_MAC_AFTE, val);
+}
+
+static int enetc4_ntmp_bitmap_init(struct ntmp_user *user)
+{
+ user->maft_eid_bitmap = bitmap_zalloc(user->maft_num_entries,
+ GFP_KERNEL);
+ if (!user->maft_eid_bitmap)
+ return -ENOMEM;
+
+ return 0;
+}
+
+static void enetc4_ntmp_bitmap_free(struct ntmp_user *user)
+{
+ bitmap_free(user->maft_eid_bitmap);
+ user->maft_eid_bitmap = NULL;
+}
+
static int enetc4_init_ntmp_user(struct enetc_si *si)
{
struct ntmp_user *user = &si->ntmp_user;
+ int err;
/* For ENETC 4.1, all table versions are 0 */
memset(&user->tbl, 0, sizeof(user->tbl));
- return enetc4_setup_cbdr(si);
+ err = enetc4_setup_cbdr(si);
+ if (err)
+ return err;
+
+ enetc4_get_ntmp_caps(si);
+ err = enetc4_ntmp_bitmap_init(user);
+ if (err)
+ goto teardown_cbdr;
+
+ return 0;
+
+teardown_cbdr:
+ enetc4_teardown_cbdr(si);
+
+ return err;
}
static void enetc4_free_ntmp_user(struct enetc_si *si)
{
+ enetc4_ntmp_bitmap_free(&si->ntmp_user);
enetc4_teardown_cbdr(si);
}
@@ -422,7 +473,7 @@ static int enetc4_pf_init(struct enetc_pf *pf)
err = enetc4_init_ntmp_user(pf->si);
if (err) {
- dev_err(dev, "Failed to init CBDR\n");
+ dev_err(dev, "Failed to init NTMP user\n");
return err;
}
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pf.h b/drivers/net/ethernet/freescale/enetc/enetc_pf.h
index 285b7e5c48fd..6f15f9ea1664 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_pf.h
+++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.h
@@ -22,7 +22,6 @@ struct enetc_port_caps {
int num_msix;
int num_rx_bdr;
int num_tx_bdr;
- int mac_filter_num;
};
struct enetc_pf;
@@ -60,8 +59,6 @@ struct enetc_pf {
struct enetc_port_caps caps;
const struct enetc_pf_ops *ops;
-
- int num_mfe; /* number of mac address filter table entries */
};
#define phylink_to_enetc_pf(config) \
diff --git a/include/linux/fsl/ntmp.h b/include/linux/fsl/ntmp.h
index d3b6c476b91a..764ef2892608 100644
--- a/include/linux/fsl/ntmp.h
+++ b/include/linux/fsl/ntmp.h
@@ -75,8 +75,10 @@ struct ntmp_user {
/* NTMP table bitmaps for resource management */
u32 ett_bitmap_size;
u32 ect_bitmap_size;
+ u16 maft_num_entries;
unsigned long *ett_gid_bitmap; /* only valid for switch */
unsigned long *ect_gid_bitmap; /* only valid for switch */
+ unsigned long *maft_eid_bitmap; /* only valid for ENETC */
};
struct maft_entry_data {
--
2.34.1
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH v2 net-next 05/14] net: enetc: use PCI device name for debugfs directory
2026-07-02 2:57 [PATCH v2 net-next 00/14] net: enetc: cleanups and improvements wei.fang
` (3 preceding siblings ...)
2026-07-02 2:57 ` [PATCH v2 net-next 04/14] net: enetc: improve MAFT entry management with bitmap tracking wei.fang
@ 2026-07-02 2:57 ` wei.fang
2026-07-02 2:57 ` [PATCH v2 net-next 06/14] net: enetc: simplify enetc4_set_port_speed() wei.fang
` (8 subsequent siblings)
13 siblings, 0 replies; 25+ messages in thread
From: wei.fang @ 2026-07-02 2:57 UTC (permalink / raw)
To: claudiu.manoil, vladimir.oltean, xiaoning.wang, andrew+netdev,
davem, edumazet, kuba, pabeni, linux, wei.fang, chleroy
Cc: imx, netdev, linux-kernel, linuxppc-dev, linux-arm-kernel
From: Wei Fang <wei.fang@nxp.com>
enetc_create_debugfs() is called right after register_netdev(), at which
point ndev->name still holds the format template "eth%d" rather than the
final assigned name (e.g., via udev rules).
Use pci_name() instead of netdev_name() to name the debugfs directory.
The PCI device name is unique, stable, and available from the start,
making it a more reliable identifier for the debugfs entry.
Signed-off-by: Wei Fang <wei.fang@nxp.com>
---
drivers/net/ethernet/freescale/enetc/enetc4_debugfs.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/freescale/enetc/enetc4_debugfs.c b/drivers/net/ethernet/freescale/enetc/enetc4_debugfs.c
index 4a769d9e5679..be378bf8f74d 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc4_debugfs.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc4_debugfs.c
@@ -81,10 +81,9 @@ DEFINE_SHOW_ATTRIBUTE(enetc_mac_filter);
void enetc_create_debugfs(struct enetc_si *si)
{
- struct net_device *ndev = si->ndev;
struct dentry *root;
- root = debugfs_create_dir(netdev_name(ndev), NULL);
+ root = debugfs_create_dir(pci_name(si->pdev), NULL);
if (IS_ERR(root))
return;
--
2.34.1
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH v2 net-next 06/14] net: enetc: simplify enetc4_set_port_speed()
2026-07-02 2:57 [PATCH v2 net-next 00/14] net: enetc: cleanups and improvements wei.fang
` (4 preceding siblings ...)
2026-07-02 2:57 ` [PATCH v2 net-next 05/14] net: enetc: use PCI device name for debugfs directory wei.fang
@ 2026-07-02 2:57 ` wei.fang
2026-07-02 17:32 ` Maxime Chevallier
2026-07-03 3:27 ` sashiko-bot
2026-07-02 2:57 ` [PATCH v2 net-next 07/14] net: enetc: differentiate phylink capabilities for pseudo-MAC and standalone MAC wei.fang
` (7 subsequent siblings)
13 siblings, 2 replies; 25+ messages in thread
From: wei.fang @ 2026-07-02 2:57 UTC (permalink / raw)
To: claudiu.manoil, vladimir.oltean, xiaoning.wang, andrew+netdev,
davem, edumazet, kuba, pabeni, linux, wei.fang, chleroy
Cc: imx, netdev, linux-kernel, linuxppc-dev, linux-arm-kernel
From: Wei Fang <wei.fang@nxp.com>
Since phylink only passes valid speed values to mac_link_up, the switch
statement with its default fallback to SPEED_10 is unnecessary. Replace
it with a direct call to PCR_PSPEED_VAL(). Also update PCR_PSPEED_VAL()
to use FIELD_PREP() for proper field masking instead of an open-coded
shift.
Signed-off-by: Wei Fang <wei.fang@nxp.com>
---
.../net/ethernet/freescale/enetc/enetc4_hw.h | 2 +-
.../net/ethernet/freescale/enetc/enetc4_pf.c | 19 +++----------------
2 files changed, 4 insertions(+), 17 deletions(-)
diff --git a/drivers/net/ethernet/freescale/enetc/enetc4_hw.h b/drivers/net/ethernet/freescale/enetc/enetc4_hw.h
index 6a8f2ed56017..dea1fd0b8175 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc4_hw.h
+++ b/drivers/net/ethernet/freescale/enetc/enetc4_hw.h
@@ -148,7 +148,7 @@
#define PCR_L2DOSE BIT(4)
#define PCR_TIMER_CS BIT(8)
#define PCR_PSPEED GENMASK(29, 16)
-#define PCR_PSPEED_VAL(speed) (((speed) / 10 - 1) << 16)
+#define PCR_PSPEED_VAL(s) FIELD_PREP(PCR_PSPEED, ((s) / 10 - 1))
/* Port MAC address register 0/1 */
#define ENETC4_PMAR0 0x4020
diff --git a/drivers/net/ethernet/freescale/enetc/enetc4_pf.c b/drivers/net/ethernet/freescale/enetc/enetc4_pf.c
index b966637572a7..db7bad2c3cbd 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc4_pf.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc4_pf.c
@@ -631,23 +631,10 @@ static void enetc4_set_port_speed(struct enetc_ndev_priv *priv, int speed)
if (speed == old_speed)
return;
- val = enetc_port_rd(&priv->si->hw, ENETC4_PCR);
- val &= ~PCR_PSPEED;
-
- switch (speed) {
- case SPEED_100:
- case SPEED_1000:
- case SPEED_2500:
- case SPEED_10000:
- val |= (PCR_PSPEED & PCR_PSPEED_VAL(speed));
- break;
- case SPEED_10:
- default:
- val |= (PCR_PSPEED & PCR_PSPEED_VAL(SPEED_10));
- }
-
- priv->speed = speed;
+ val = enetc_port_rd(&priv->si->hw, ENETC4_PCR) & (~PCR_PSPEED);
+ val |= PCR_PSPEED_VAL(speed);
enetc_port_wr(&priv->si->hw, ENETC4_PCR, val);
+ priv->speed = speed;
}
static void enetc4_set_rgmii_mac(struct enetc_pf *pf, int speed, int duplex)
--
2.34.1
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH v2 net-next 07/14] net: enetc: differentiate phylink capabilities for pseudo-MAC and standalone MAC
2026-07-02 2:57 [PATCH v2 net-next 00/14] net: enetc: cleanups and improvements wei.fang
` (5 preceding siblings ...)
2026-07-02 2:57 ` [PATCH v2 net-next 06/14] net: enetc: simplify enetc4_set_port_speed() wei.fang
@ 2026-07-02 2:57 ` wei.fang
2026-07-02 17:30 ` Maxime Chevallier
2026-07-03 3:27 ` sashiko-bot
2026-07-02 2:57 ` [PATCH v2 net-next 08/14] net: enetc: remove invalid code from enetc4_pl_mac_link_up() wei.fang
` (6 subsequent siblings)
13 siblings, 2 replies; 25+ messages in thread
From: wei.fang @ 2026-07-02 2:57 UTC (permalink / raw)
To: claudiu.manoil, vladimir.oltean, xiaoning.wang, andrew+netdev,
davem, edumazet, kuba, pabeni, linux, wei.fang, chleroy
Cc: imx, netdev, linux-kernel, linuxppc-dev, linux-arm-kernel
From: Claudiu Manoil <claudiu.manoil@nxp.com>
The ENETC pseudo-MACs are proprietary internal links that do not
implement any standard MII interface, so restrict their supported PHY
interface modes to PHY_INTERFACE_MODE_INTERNAL only.
Since pseudo-MACs can operate at any speed between 10Mbps and 25Gbps
in multiples of 10Mbps, set their MAC capabilities to cover the full
range of standard full-duplex speeds: 10/100/1000/2500/5000/10000/
20000/25000 Mbps.
For standalone ENETC, expand the supported interface modes to include
10GBASER and XGMII in addition to the existing RGMII, SGMII, 1000BASEX,
2500BASEX and USXGMII modes, with MAC capabilities up to 10G. MAC_1000
is replaced with MAC_1000FD to explicitly exclude 1000M half-duplex,
which is not supported.
Signed-off-by: Claudiu Manoil <claudiu.manoil@nxp.com>
Signed-off-by: Wei Fang <wei.fang@nxp.com>
---
drivers/net/ethernet/freescale/enetc/enetc.h | 2 +-
.../freescale/enetc/enetc_pf_common.c | 47 ++++++++++++++-----
2 files changed, 35 insertions(+), 14 deletions(-)
diff --git a/drivers/net/ethernet/freescale/enetc/enetc.h b/drivers/net/ethernet/freescale/enetc/enetc.h
index 06a9f1ee0970..8839cfb49bcf 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc.h
+++ b/drivers/net/ethernet/freescale/enetc/enetc.h
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */
-/* Copyright 2017-2019 NXP */
+/* Copyright 2017-2019, 2025-2026 NXP */
#include <linux/timer.h>
#include <linux/pci.h>
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pf_common.c b/drivers/net/ethernet/freescale/enetc/enetc_pf_common.c
index 3597cb81a7cc..6ccf9b909054 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_pf_common.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc_pf_common.c
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
-/* Copyright 2024 NXP */
+/* Copyright 2024-2026 NXP */
#include <linux/fsl/enetc_mdio.h>
#include <linux/of_mdio.h>
@@ -359,7 +359,9 @@ static bool enetc_port_has_pcs(struct enetc_pf *pf)
return (pf->if_mode == PHY_INTERFACE_MODE_SGMII ||
pf->if_mode == PHY_INTERFACE_MODE_1000BASEX ||
pf->if_mode == PHY_INTERFACE_MODE_2500BASEX ||
- pf->if_mode == PHY_INTERFACE_MODE_USXGMII);
+ pf->if_mode == PHY_INTERFACE_MODE_USXGMII ||
+ pf->if_mode == PHY_INTERFACE_MODE_10GBASER ||
+ pf->if_mode == PHY_INTERFACE_MODE_XGMII);
}
int enetc_mdiobus_create(struct enetc_pf *pf, struct device_node *node)
@@ -400,25 +402,44 @@ int enetc_phylink_create(struct enetc_ndev_priv *priv, struct device_node *node,
{
struct enetc_pf *pf = enetc_si_priv(priv->si);
struct phylink *phylink;
+ unsigned long mac_caps;
int err;
pf->phylink_config.dev = &priv->ndev->dev;
pf->phylink_config.type = PHYLINK_NETDEV;
- pf->phylink_config.mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
- MAC_10 | MAC_100 | MAC_1000 | MAC_2500FD;
__set_bit(PHY_INTERFACE_MODE_INTERNAL,
pf->phylink_config.supported_interfaces);
- __set_bit(PHY_INTERFACE_MODE_SGMII,
- pf->phylink_config.supported_interfaces);
- __set_bit(PHY_INTERFACE_MODE_1000BASEX,
- pf->phylink_config.supported_interfaces);
- __set_bit(PHY_INTERFACE_MODE_2500BASEX,
- pf->phylink_config.supported_interfaces);
- __set_bit(PHY_INTERFACE_MODE_USXGMII,
- pf->phylink_config.supported_interfaces);
- phy_interface_set_rgmii(pf->phylink_config.supported_interfaces);
+ mac_caps = MAC_ASYM_PAUSE | MAC_SYM_PAUSE;
+ if (!enetc_is_pseudo_mac(priv->si)) {
+ mac_caps |= MAC_10 | MAC_100 | MAC_1000FD | MAC_2500FD;
+
+ __set_bit(PHY_INTERFACE_MODE_SGMII,
+ pf->phylink_config.supported_interfaces);
+ __set_bit(PHY_INTERFACE_MODE_1000BASEX,
+ pf->phylink_config.supported_interfaces);
+ __set_bit(PHY_INTERFACE_MODE_2500BASEX,
+ pf->phylink_config.supported_interfaces);
+ __set_bit(PHY_INTERFACE_MODE_USXGMII,
+ pf->phylink_config.supported_interfaces);
+
+ if (!is_enetc_rev1(priv->si)) {
+ mac_caps |= MAC_5000FD | MAC_10000FD;
+ __set_bit(PHY_INTERFACE_MODE_10GBASER,
+ pf->phylink_config.supported_interfaces);
+ __set_bit(PHY_INTERFACE_MODE_XGMII,
+ pf->phylink_config.supported_interfaces);
+ }
+
+ phy_interface_set_rgmii(pf->phylink_config.supported_interfaces);
+ } else {
+ mac_caps |= MAC_10FD | MAC_100FD | MAC_1000FD | MAC_2500FD |
+ MAC_5000FD | MAC_10000FD | MAC_20000FD |
+ MAC_25000FD;
+ }
+
+ pf->phylink_config.mac_capabilities = mac_caps;
phylink = phylink_create(&pf->phylink_config, of_fwnode_handle(node),
pf->if_mode, ops);
if (IS_ERR(phylink)) {
--
2.34.1
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH v2 net-next 08/14] net: enetc: remove invalid code from enetc4_pl_mac_link_up()
2026-07-02 2:57 [PATCH v2 net-next 00/14] net: enetc: cleanups and improvements wei.fang
` (6 preceding siblings ...)
2026-07-02 2:57 ` [PATCH v2 net-next 07/14] net: enetc: differentiate phylink capabilities for pseudo-MAC and standalone MAC wei.fang
@ 2026-07-02 2:57 ` wei.fang
2026-07-02 17:35 ` Maxime Chevallier
2026-07-02 2:57 ` [PATCH v2 net-next 09/14] net: enetc: remove enetc4_set_default_si_vlan_promisc() wei.fang
` (5 subsequent siblings)
13 siblings, 1 reply; 25+ messages in thread
From: wei.fang @ 2026-07-02 2:57 UTC (permalink / raw)
To: claudiu.manoil, vladimir.oltean, xiaoning.wang, andrew+netdev,
davem, edumazet, kuba, pabeni, linux, wei.fang, chleroy
Cc: imx, netdev, linux-kernel, linuxppc-dev, linux-arm-kernel
From: Wei Fang <wei.fang@nxp.com>
When adding phylink MAC operations support to the NETC switch driver,
Russell King pointed out several pieces of invalid logic in the
.mac_link_up() implementation (see [1] and [2]):
1) Half-duplex backpressure is not supported by the kernel, Ethernet
relies on packet dropping for congestion management.
2) phylink_autoneg_inband() is unnecessary, as RGMII in-band status is
not supported.
3) TX and RX pause are disabled in half-duplex mode, so there is no
need to override them in .mac_link_up().
The same invalid logic is also present in enetc4_pl_mac_link_up(), so
remove the invalid code from it.
Link: https://lore.kernel.org/imx/acEIQqI-_oyCym8O@shell.armlinux.org.uk/ # 1
Link: https://lore.kernel.org/imx/acEFwqmAvWls_9Ef@shell.armlinux.org.uk/ # 2
Signed-off-by: Wei Fang <wei.fang@nxp.com>
---
.../net/ethernet/freescale/enetc/enetc4_hw.h | 1 -
.../net/ethernet/freescale/enetc/enetc4_pf.c | 35 +------------------
2 files changed, 1 insertion(+), 35 deletions(-)
diff --git a/drivers/net/ethernet/freescale/enetc/enetc4_hw.h b/drivers/net/ethernet/freescale/enetc/enetc4_hw.h
index dea1fd0b8175..7a3ccc94b036 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc4_hw.h
+++ b/drivers/net/ethernet/freescale/enetc/enetc4_hw.h
@@ -198,7 +198,6 @@
#define PM_CMD_CFG_CNT_FRM_EN BIT(13)
#define PM_CMD_CFG_TXP BIT(15)
#define PM_CMD_CFG_SEND_IDLE BIT(16)
-#define PM_CMD_CFG_HD_FCEN BIT(18)
#define PM_CMD_CFG_SFD BIT(21)
#define PM_CMD_CFG_TX_FLUSH BIT(22)
#define PM_CMD_CFG_TX_LOWP_EN BIT(23)
diff --git a/drivers/net/ethernet/freescale/enetc/enetc4_pf.c b/drivers/net/ethernet/freescale/enetc/enetc4_pf.c
index db7bad2c3cbd..a77ef62672c7 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc4_pf.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc4_pf.c
@@ -588,11 +588,6 @@ static void enetc4_mac_config(struct enetc_pf *pf, unsigned int mode,
case PHY_INTERFACE_MODE_RGMII_RXID:
case PHY_INTERFACE_MODE_RGMII_TXID:
val |= IFMODE_RGMII;
- /* We need to enable auto-negotiation for the MAC
- * if its RGMII interface support In-Band status.
- */
- if (phylink_autoneg_inband(mode))
- val |= PM_IF_MODE_ENA;
break;
case PHY_INTERFACE_MODE_RMII:
val |= IFMODE_RMII;
@@ -690,22 +685,6 @@ static void enetc4_set_rmii_mac(struct enetc_pf *pf, int speed, int duplex)
enetc_port_mac_wr(si, ENETC4_PM_IF_MODE(0), val);
}
-static void enetc4_set_hd_flow_control(struct enetc_pf *pf, bool enable)
-{
- struct enetc_si *si = pf->si;
- u32 old_val, val;
-
- if (!pf->caps.half_duplex)
- return;
-
- old_val = enetc_port_mac_rd(si, ENETC4_PM_CMD_CFG(0));
- val = u32_replace_bits(old_val, enable ? 1 : 0, PM_CMD_CFG_HD_FCEN);
- if (val == old_val)
- return;
-
- enetc_port_mac_wr(si, ENETC4_PM_CMD_CFG(0), val);
-}
-
static void enetc4_set_rx_pause(struct enetc_pf *pf, bool rx_pause)
{
struct enetc_si *si = pf->si;
@@ -881,13 +860,11 @@ static void enetc4_pl_mac_link_up(struct phylink_config *config,
struct enetc_pf *pf = phylink_to_enetc_pf(config);
struct enetc_si *si = pf->si;
struct enetc_ndev_priv *priv;
- bool hd_fc = false;
priv = netdev_priv(si->ndev);
enetc4_set_port_speed(priv, speed);
- if (!phylink_autoneg_inband(mode) &&
- phy_interface_mode_is_rgmii(interface))
+ if (phy_interface_mode_is_rgmii(interface))
enetc4_set_rgmii_mac(pf, speed, duplex);
if (interface == PHY_INTERFACE_MODE_RMII)
@@ -899,18 +876,8 @@ static void enetc4_pl_mac_link_up(struct phylink_config *config,
*/
if (priv->active_offloads & ENETC_F_QBU)
tx_pause = false;
- } else { /* DUPLEX_HALF */
- if (tx_pause || rx_pause)
- hd_fc = true;
-
- /* As per 802.3 annex 31B, PAUSE frames are only supported
- * when the link is configured for full duplex operation.
- */
- tx_pause = false;
- rx_pause = false;
}
- enetc4_set_hd_flow_control(pf, hd_fc);
enetc4_set_tx_pause(pf, priv->num_rx_rings, tx_pause);
enetc4_set_rx_pause(pf, rx_pause);
enetc4_mac_tx_enable(pf);
--
2.34.1
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH v2 net-next 09/14] net: enetc: remove enetc4_set_default_si_vlan_promisc()
2026-07-02 2:57 [PATCH v2 net-next 00/14] net: enetc: cleanups and improvements wei.fang
` (7 preceding siblings ...)
2026-07-02 2:57 ` [PATCH v2 net-next 08/14] net: enetc: remove invalid code from enetc4_pl_mac_link_up() wei.fang
@ 2026-07-02 2:57 ` wei.fang
2026-07-02 2:57 ` [PATCH v2 net-next 10/14] net: enetc: refactor SI VLAN promiscuous mode configuration wei.fang
` (4 subsequent siblings)
13 siblings, 0 replies; 25+ messages in thread
From: wei.fang @ 2026-07-02 2:57 UTC (permalink / raw)
To: claudiu.manoil, vladimir.oltean, xiaoning.wang, andrew+netdev,
davem, edumazet, kuba, pabeni, linux, wei.fang, chleroy
Cc: imx, netdev, linux-kernel, linuxppc-dev, linux-arm-kernel
From: Wei Fang <wei.fang@nxp.com>
PF performs PCI FLR during driver probe, which resets the PSIPVMR
register to its default state where VLAN promiscuous mode is enabled
for all SIs.
The explicit call to enetc4_set_default_si_vlan_promisc() in probe
is therefore redundant. Remove it.
Signed-off-by: Wei Fang <wei.fang@nxp.com>
---
drivers/net/ethernet/freescale/enetc/enetc4_pf.c | 13 -------------
1 file changed, 13 deletions(-)
diff --git a/drivers/net/ethernet/freescale/enetc/enetc4_pf.c b/drivers/net/ethernet/freescale/enetc/enetc4_pf.c
index a77ef62672c7..88ad99cecc9c 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc4_pf.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc4_pf.c
@@ -310,17 +310,6 @@ static void enetc4_pf_set_si_vlan_promisc(struct enetc_hw *hw, int si, bool en)
enetc_port_wr(hw, ENETC4_PSIPVMR, val);
}
-static void enetc4_set_default_si_vlan_promisc(struct enetc_pf *pf)
-{
- struct enetc_hw *hw = &pf->si->hw;
- int num_si = pf->caps.num_vsi + 1;
- int i;
-
- /* enforce VLAN promiscuous mode for all SIs */
- for (i = 0; i < num_si; i++)
- enetc4_pf_set_si_vlan_promisc(hw, i, true);
-}
-
/* Allocate the number of MSI-X vectors for per SI. */
static void enetc4_set_si_msix_num(struct enetc_pf *pf)
{
@@ -364,8 +353,6 @@ static void enetc4_configure_port_si(struct enetc_pf *pf)
/* Outer VLAN tag will be used for VLAN filtering */
enetc_port_wr(hw, ENETC4_PSIVLANFMR, PSIVLANFMR_VS);
- enetc4_set_default_si_vlan_promisc(pf);
-
/* Disable SI MAC multicast & unicast promiscuous */
enetc_port_wr(hw, ENETC4_PSIPMMR, 0);
--
2.34.1
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH v2 net-next 10/14] net: enetc: refactor SI VLAN promiscuous mode configuration
2026-07-02 2:57 [PATCH v2 net-next 00/14] net: enetc: cleanups and improvements wei.fang
` (8 preceding siblings ...)
2026-07-02 2:57 ` [PATCH v2 net-next 09/14] net: enetc: remove enetc4_set_default_si_vlan_promisc() wei.fang
@ 2026-07-02 2:57 ` wei.fang
2026-07-03 3:27 ` sashiko-bot
2026-07-02 2:57 ` [PATCH v2 net-next 11/14] net: enetc: move enetc_set_si_vlan_promisc() to enetc_pf_common.c wei.fang
` (3 subsequent siblings)
13 siblings, 1 reply; 25+ messages in thread
From: wei.fang @ 2026-07-02 2:57 UTC (permalink / raw)
To: claudiu.manoil, vladimir.oltean, xiaoning.wang, andrew+netdev,
davem, edumazet, kuba, pabeni, linux, wei.fang, chleroy
Cc: imx, netdev, linux-kernel, linuxppc-dev, linux-arm-kernel
From: Wei Fang <wei.fang@nxp.com>
Since a PCI FLR (Function Level Reset) is performed during probe, and
the hardware enables VLAN promiscuous mode for all SIs by default after
reset, there is no need to explicitly set it in enetc_configure_port().
Remove the redundant initialization of vlan_promisc_simap and the call
to enetc_set_vlan_promisc() from enetc_configure_port().
Remove the enetc_set_vlan_promisc(), enetc_enable_si_vlan_promisc() and
enetc_disable_si_vlan_promisc() functions, and introduce a new unified
function enetc_set_si_vlan_promisc() to enable or disable VLAN
promiscuous mode for a specific SI. This simplifies the logic and makes
the interface more straightforward.
As ENETC V4 only changes the address offset of PSIPVMR register compared
to V1 without any functional difference, enetc_set_si_vlan_promisc() can
be moved to enetc_pf_common.c in the future with minor adjustments to be
reused by the ENETC V4 driver
Signed-off-by: Wei Fang <wei.fang@nxp.com>
---
.../net/ethernet/freescale/enetc/enetc_hw.h | 5 ++-
.../net/ethernet/freescale/enetc/enetc_pf.c | 35 +++++++------------
.../net/ethernet/freescale/enetc/enetc_pf.h | 1 -
3 files changed, 14 insertions(+), 27 deletions(-)
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_hw.h b/drivers/net/ethernet/freescale/enetc/enetc_hw.h
index 66bfda60da9c..16da732dc5de 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_hw.h
+++ b/drivers/net/ethernet/freescale/enetc/enetc_hw.h
@@ -185,9 +185,8 @@ enum enetc_bdr_type {TX, RX};
#define PSIPMMR_SI_MAC_MP(n) BIT((n) + 16)
#define ENETC_PSIPVMR 0x001c
-#define ENETC_VLAN_PROMISC_MAP_ALL 0x7
-#define ENETC_PSIPVMR_SET_VP(simap) ((simap) & 0x7)
-#define ENETC_PSIPVMR_SET_VUTA(simap) (((simap) & 0x7) << 16)
+#define PSIPVMR_SI_VLAN_P(n) BIT(n) /* n = SI index */
+
#define ENETC_PSIPMAR0(n) (0x0100 + (n) * 0x8) /* n = SI index */
#define ENETC_PSIPMAR1(n) (0x0104 + (n) * 0x8)
#define ENETC_PVCLCTR 0x0208
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pf.c b/drivers/net/ethernet/freescale/enetc/enetc_pf.c
index db2a800a7aaf..096ccb35508c 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_pf.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.c
@@ -42,24 +42,20 @@ static void enetc_pf_destroy_pcs(struct phylink_pcs *pcs)
lynx_pcs_destroy(pcs);
}
-static void enetc_set_vlan_promisc(struct enetc_hw *hw, char si_map)
+static void enetc_set_si_vlan_promisc(struct enetc_si *si, int si_id,
+ bool promisc)
{
- u32 val = enetc_port_rd(hw, ENETC_PSIPVMR);
+ struct enetc_hw *hw = &si->hw;
+ u32 val;
- val &= ~ENETC_PSIPVMR_SET_VP(ENETC_VLAN_PROMISC_MAP_ALL);
- enetc_port_wr(hw, ENETC_PSIPVMR, ENETC_PSIPVMR_SET_VP(si_map) | val);
-}
+ val = enetc_port_rd(hw, ENETC_PSIPVMR);
-static void enetc_enable_si_vlan_promisc(struct enetc_pf *pf, int si_idx)
-{
- pf->vlan_promisc_simap |= BIT(si_idx);
- enetc_set_vlan_promisc(&pf->si->hw, pf->vlan_promisc_simap);
-}
+ if (promisc)
+ val |= PSIPVMR_SI_VLAN_P(si_id);
+ else
+ val &= ~PSIPVMR_SI_VLAN_P(si_id);
-static void enetc_disable_si_vlan_promisc(struct enetc_pf *pf, int si_idx)
-{
- pf->vlan_promisc_simap &= ~BIT(si_idx);
- enetc_set_vlan_promisc(&pf->si->hw, pf->vlan_promisc_simap);
+ enetc_port_wr(hw, ENETC_PSIPVMR, val);
}
static void enetc_set_isol_vlan(struct enetc_hw *hw, int si, u16 vlan, u8 qos)
@@ -442,10 +438,6 @@ static void enetc_configure_port(struct enetc_pf *pf)
/* split up RFS entries */
enetc_port_assign_rfs_entries(pf->si);
- /* enforce VLAN promisc mode for all SIs */
- pf->vlan_promisc_simap = ENETC_VLAN_PROMISC_MAP_ALL;
- enetc_set_vlan_promisc(hw, pf->vlan_promisc_simap);
-
enetc_port_wr(hw, ENETC_PSIPMMR, 0);
/* enable port */
@@ -466,12 +458,9 @@ static int enetc_pf_set_features(struct net_device *ndev,
}
if (changed & NETIF_F_HW_VLAN_CTAG_FILTER) {
- struct enetc_pf *pf = enetc_si_priv(priv->si);
+ bool promisc = !(features & NETIF_F_HW_VLAN_CTAG_FILTER);
- if (!!(features & NETIF_F_HW_VLAN_CTAG_FILTER))
- enetc_disable_si_vlan_promisc(pf, 0);
- else
- enetc_enable_si_vlan_promisc(pf, 0);
+ enetc_set_si_vlan_promisc(priv->si, 0, promisc);
}
if (changed & NETIF_F_LOOPBACK)
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pf.h b/drivers/net/ethernet/freescale/enetc/enetc_pf.h
index 6f15f9ea1664..574ab4e76d8b 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_pf.h
+++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.h
@@ -46,7 +46,6 @@ struct enetc_pf {
struct work_struct msg_task;
char msg_int_name[ENETC_INT_NAME_MAX];
- char vlan_promisc_simap; /* bitmap of SIs in VLAN promisc mode */
DECLARE_BITMAP(vlan_ht_filter, ENETC_VLAN_HT_SIZE);
DECLARE_BITMAP(active_vlans, VLAN_N_VID);
--
2.34.1
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH v2 net-next 11/14] net: enetc: move enetc_set_si_vlan_promisc() to enetc_pf_common.c
2026-07-02 2:57 [PATCH v2 net-next 00/14] net: enetc: cleanups and improvements wei.fang
` (9 preceding siblings ...)
2026-07-02 2:57 ` [PATCH v2 net-next 10/14] net: enetc: refactor SI VLAN promiscuous mode configuration wei.fang
@ 2026-07-02 2:57 ` wei.fang
2026-07-02 2:57 ` [PATCH v2 net-next 12/14] net: enetc: remove redundant num_vsi field from enetc_port_caps wei.fang
` (2 subsequent siblings)
13 siblings, 0 replies; 25+ messages in thread
From: wei.fang @ 2026-07-02 2:57 UTC (permalink / raw)
To: claudiu.manoil, vladimir.oltean, xiaoning.wang, andrew+netdev,
davem, edumazet, kuba, pabeni, linux, wei.fang, chleroy
Cc: imx, netdev, linux-kernel, linuxppc-dev, linux-arm-kernel
From: Wei Fang <wei.fang@nxp.com>
The PSIPVMR in ENETC v4 has the same bit layout and functionality as the
PSIPVMR register in ENETC v1: bit n (n <= 15) controls VLAN promiscuous
mode for SI n. The only difference between the two hardware generations
is the register address offset.
Since the register functionality is identical, the VLAN promiscuous mode
setting code can be shared between ENETC v1 and v4 drivers.
Move enetc_set_si_vlan_promisc() from enetc_pf.c to enetc_pf_common.c
and export it so that it can be shared between the two drivers. Add a
revision check using is_enetc_rev1() to select the correct register
offset (ENETC_PSIPVMR for v1 and ENETC4_PSIPVMR for v4) while keeping
the same logic.
Remove the v4-specific enetc4_pf_set_si_vlan_promisc() from enetc4_pf.c
and replace its call site with the new common enetc_set_si_vlan_promisc()
to eliminate code duplication.
Signed-off-by: Wei Fang <wei.fang@nxp.com>
---
.../net/ethernet/freescale/enetc/enetc4_pf.c | 15 +------------
.../net/ethernet/freescale/enetc/enetc_pf.c | 16 --------------
.../freescale/enetc/enetc_pf_common.c | 22 +++++++++++++++++++
.../freescale/enetc/enetc_pf_common.h | 1 +
4 files changed, 24 insertions(+), 30 deletions(-)
diff --git a/drivers/net/ethernet/freescale/enetc/enetc4_pf.c b/drivers/net/ethernet/freescale/enetc/enetc4_pf.c
index 88ad99cecc9c..d919a8645fb1 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc4_pf.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc4_pf.c
@@ -298,18 +298,6 @@ static void enetc4_allocate_si_rings(struct enetc_pf *pf)
enetc4_default_rings_allocation(pf);
}
-static void enetc4_pf_set_si_vlan_promisc(struct enetc_hw *hw, int si, bool en)
-{
- u32 val = enetc_port_rd(hw, ENETC4_PSIPVMR);
-
- if (en)
- val |= BIT(si);
- else
- val &= ~BIT(si);
-
- enetc_port_wr(hw, ENETC4_PSIPVMR, val);
-}
-
/* Allocate the number of MSI-X vectors for per SI. */
static void enetc4_set_si_msix_num(struct enetc_pf *pf)
{
@@ -517,12 +505,11 @@ static int enetc4_pf_set_features(struct net_device *ndev,
{
netdev_features_t changed = ndev->features ^ features;
struct enetc_ndev_priv *priv = netdev_priv(ndev);
- struct enetc_hw *hw = &priv->si->hw;
if (changed & NETIF_F_HW_VLAN_CTAG_FILTER) {
bool promisc_en = !(features & NETIF_F_HW_VLAN_CTAG_FILTER);
- enetc4_pf_set_si_vlan_promisc(hw, 0, promisc_en);
+ enetc_set_si_vlan_promisc(priv->si, 0, promisc_en);
}
if (changed & NETIF_F_LOOPBACK)
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pf.c b/drivers/net/ethernet/freescale/enetc/enetc_pf.c
index 096ccb35508c..ac282d17c0d3 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_pf.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.c
@@ -42,22 +42,6 @@ static void enetc_pf_destroy_pcs(struct phylink_pcs *pcs)
lynx_pcs_destroy(pcs);
}
-static void enetc_set_si_vlan_promisc(struct enetc_si *si, int si_id,
- bool promisc)
-{
- struct enetc_hw *hw = &si->hw;
- u32 val;
-
- val = enetc_port_rd(hw, ENETC_PSIPVMR);
-
- if (promisc)
- val |= PSIPVMR_SI_VLAN_P(si_id);
- else
- val &= ~PSIPVMR_SI_VLAN_P(si_id);
-
- enetc_port_wr(hw, ENETC_PSIPVMR, val);
-}
-
static void enetc_set_isol_vlan(struct enetc_hw *hw, int si, u16 vlan, u8 qos)
{
u32 val = 0;
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pf_common.c b/drivers/net/ethernet/freescale/enetc/enetc_pf_common.c
index 6ccf9b909054..fdfb17093538 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_pf_common.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc_pf_common.c
@@ -171,6 +171,28 @@ void enetc_set_si_mc_hash_filter(struct enetc_si *si, int si_id, u64 hash)
}
EXPORT_SYMBOL_GPL(enetc_set_si_mc_hash_filter);
+void enetc_set_si_vlan_promisc(struct enetc_si *si, int si_id, bool promisc)
+{
+ struct enetc_hw *hw = &si->hw;
+ int psipvmr_off;
+ u32 val;
+
+ if (is_enetc_rev1(si))
+ psipvmr_off = ENETC_PSIPVMR;
+ else
+ psipvmr_off = ENETC4_PSIPVMR;
+
+ val = enetc_port_rd(hw, psipvmr_off);
+
+ if (promisc)
+ val |= PSIPVMR_SI_VLAN_P(si_id);
+ else
+ val &= ~PSIPVMR_SI_VLAN_P(si_id);
+
+ enetc_port_wr(hw, psipvmr_off, val);
+}
+EXPORT_SYMBOL_GPL(enetc_set_si_vlan_promisc);
+
void enetc_pf_netdev_setup(struct enetc_si *si, struct net_device *ndev,
const struct net_device_ops *ndev_ops)
{
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pf_common.h b/drivers/net/ethernet/freescale/enetc/enetc_pf_common.h
index bf9029b0a017..8243ce0de57f 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_pf_common.h
+++ b/drivers/net/ethernet/freescale/enetc/enetc_pf_common.h
@@ -21,6 +21,7 @@ void enetc_set_si_uc_promisc(struct enetc_si *si, int si_id, bool promisc);
void enetc_set_si_mc_promisc(struct enetc_si *si, int si_id, bool promisc);
void enetc_set_si_uc_hash_filter(struct enetc_si *si, int si_id, u64 hash);
void enetc_set_si_mc_hash_filter(struct enetc_si *si, int si_id, u64 hash);
+void enetc_set_si_vlan_promisc(struct enetc_si *si, int si_id, bool promisc);
static inline u16 enetc_get_ip_revision(struct enetc_hw *hw)
{
--
2.34.1
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH v2 net-next 12/14] net: enetc: remove redundant num_vsi field from enetc_port_caps
2026-07-02 2:57 [PATCH v2 net-next 00/14] net: enetc: cleanups and improvements wei.fang
` (10 preceding siblings ...)
2026-07-02 2:57 ` [PATCH v2 net-next 11/14] net: enetc: move enetc_set_si_vlan_promisc() to enetc_pf_common.c wei.fang
@ 2026-07-02 2:57 ` wei.fang
2026-07-02 2:57 ` [PATCH v2 net-next 13/14] net: enetc: use alloc_etherdev_mqs() to create netdev for VF driver wei.fang
2026-07-02 2:57 ` [PATCH v2 net-next 14/14] net: enetc: use kzalloc_flex() for enetc_psfp_gate allocation wei.fang
13 siblings, 0 replies; 25+ messages in thread
From: wei.fang @ 2026-07-02 2:57 UTC (permalink / raw)
To: claudiu.manoil, vladimir.oltean, xiaoning.wang, andrew+netdev,
davem, edumazet, kuba, pabeni, linux, wei.fang, chleroy
Cc: imx, netdev, linux-kernel, linuxppc-dev, linux-arm-kernel
From: Wei Fang <wei.fang@nxp.com>
The num_vsi field in struct enetc_port_caps is populated by reading the
NUM_VSI field of the ECAPR1 register, which reports the number of VSIs
supported by the ENETC4 port. This value is equivalent to the total
number of VFs reported by the PCI SR-IOV capability, which is already
stored in pf->total_vfs during probe via pci_sriov_get_totalvfs().
Since pf->total_vfs carries the same information and is already
available throughout the driver, there is no need to read and cache
num_vsi separately in the port capabilities structure. Remove the
num_vsi field from enetc_port_caps and the associated ECAPR1_NUM_VSI
macro, and replace all uses of pf->caps.num_vsi with pf->total_vfs in
the ring allocation, MSI-X configuration, SI enable, and debugfs code
paths.
Signed-off-by: Wei Fang <wei.fang@nxp.com>
---
.../ethernet/freescale/enetc/enetc4_debugfs.c | 13 +++----
.../net/ethernet/freescale/enetc/enetc4_hw.h | 1 -
.../net/ethernet/freescale/enetc/enetc4_pf.c | 37 +++++++++----------
.../net/ethernet/freescale/enetc/enetc_pf.h | 1 -
4 files changed, 23 insertions(+), 29 deletions(-)
diff --git a/drivers/net/ethernet/freescale/enetc/enetc4_debugfs.c b/drivers/net/ethernet/freescale/enetc/enetc4_debugfs.c
index be378bf8f74d..5029038bf99f 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc4_debugfs.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc4_debugfs.c
@@ -28,17 +28,14 @@ static void enetc_show_si_mac_hash_filter(struct seq_file *s, int i)
static int enetc_mac_filter_show(struct seq_file *s, void *data)
{
- struct enetc_si *si = s->private;
- struct enetc_hw *hw = &si->hw;
+ struct enetc_pf *pf = enetc_si_priv(s->private);
+ struct enetc_hw *hw = &pf->si->hw;
+ int num_si = pf->total_vfs + 1;
struct maft_entry_data maft;
struct ntmp_user *user;
- struct enetc_pf *pf;
u32 val, entry_id;
- int i, num_si;
int err = 0;
-
- pf = enetc_si_priv(si);
- num_si = pf->caps.num_vsi + 1;
+ int i;
val = enetc_port_rd(hw, ENETC4_PSIPMMR);
for (i = 0; i < num_si; i++) {
@@ -52,7 +49,7 @@ static int enetc_mac_filter_show(struct seq_file *s, void *data)
for (i = 0; i < num_si; i++)
enetc_show_si_mac_hash_filter(s, i);
- user = &si->ntmp_user;
+ user = &pf->si->ntmp_user;
rtnl_lock();
if (bitmap_empty(user->maft_eid_bitmap, user->maft_num_entries))
diff --git a/drivers/net/ethernet/freescale/enetc/enetc4_hw.h b/drivers/net/ethernet/freescale/enetc/enetc4_hw.h
index 7a3ccc94b036..72b54fe02e65 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc4_hw.h
+++ b/drivers/net/ethernet/freescale/enetc/enetc4_hw.h
@@ -50,7 +50,6 @@
#define ECAPR1_NUM_MCH GENMASK(9, 8)
#define ECAPR1_NUM_UCH GENMASK(11, 10)
#define ECAPR1_NUM_MSIX GENMASK(22, 12)
-#define ECAPR1_NUM_VSI GENMASK(27, 24)
#define ECAPR1_NUM_IPV BIT(31)
#define ENETC4_ECAPR2 0x8
diff --git a/drivers/net/ethernet/freescale/enetc/enetc4_pf.c b/drivers/net/ethernet/freescale/enetc/enetc4_pf.c
index d919a8645fb1..c47ee2049aac 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc4_pf.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc4_pf.c
@@ -23,7 +23,6 @@ static void enetc4_get_port_caps(struct enetc_pf *pf)
u32 val;
val = enetc_port_rd(hw, ENETC4_ECAPR1);
- pf->caps.num_vsi = (val & ECAPR1_NUM_VSI) >> 24;
pf->caps.num_msix = ((val & ECAPR1_NUM_MSIX) >> 12) + 1;
val = enetc_port_rd(hw, ENETC4_ECAPR2);
@@ -258,34 +257,35 @@ static void enetc4_default_rings_allocation(struct enetc_pf *pf)
{
struct enetc_hw *hw = &pf->si->hw;
u32 num_rx_bdr, num_tx_bdr, val;
+ int num_vfs = pf->total_vfs;
u32 vf_tx_bdr, vf_rx_bdr;
int i, rx_rem, tx_rem;
- if (pf->caps.num_rx_bdr < ENETC_SI_MAX_RING_NUM + pf->caps.num_vsi)
- num_rx_bdr = pf->caps.num_rx_bdr - pf->caps.num_vsi;
+ if (pf->caps.num_rx_bdr < ENETC_SI_MAX_RING_NUM + num_vfs)
+ num_rx_bdr = pf->caps.num_rx_bdr - num_vfs;
else
num_rx_bdr = ENETC_SI_MAX_RING_NUM;
- if (pf->caps.num_tx_bdr < ENETC_SI_MAX_RING_NUM + pf->caps.num_vsi)
- num_tx_bdr = pf->caps.num_tx_bdr - pf->caps.num_vsi;
+ if (pf->caps.num_tx_bdr < ENETC_SI_MAX_RING_NUM + num_vfs)
+ num_tx_bdr = pf->caps.num_tx_bdr - num_vfs;
else
num_tx_bdr = ENETC_SI_MAX_RING_NUM;
val = enetc4_psicfgr0_val_construct(false, num_tx_bdr, num_rx_bdr);
enetc_port_wr(hw, ENETC4_PSICFGR0(0), val);
- if (!pf->caps.num_vsi)
+ if (!num_vfs)
return;
num_rx_bdr = pf->caps.num_rx_bdr - num_rx_bdr;
- rx_rem = num_rx_bdr % pf->caps.num_vsi;
- num_rx_bdr = num_rx_bdr / pf->caps.num_vsi;
+ rx_rem = num_rx_bdr % num_vfs;
+ num_rx_bdr = num_rx_bdr / num_vfs;
num_tx_bdr = pf->caps.num_tx_bdr - num_tx_bdr;
- tx_rem = num_tx_bdr % pf->caps.num_vsi;
- num_tx_bdr = num_tx_bdr / pf->caps.num_vsi;
+ tx_rem = num_tx_bdr % num_vfs;
+ num_tx_bdr = num_tx_bdr / num_vfs;
- for (i = 0; i < pf->caps.num_vsi; i++) {
+ for (i = 0; i < num_vfs; i++) {
vf_tx_bdr = (i < tx_rem) ? num_tx_bdr + 1 : num_tx_bdr;
vf_rx_bdr = (i < rx_rem) ? num_rx_bdr + 1 : num_rx_bdr;
val = enetc4_psicfgr0_val_construct(true, vf_tx_bdr, vf_rx_bdr);
@@ -302,26 +302,25 @@ static void enetc4_allocate_si_rings(struct enetc_pf *pf)
static void enetc4_set_si_msix_num(struct enetc_pf *pf)
{
struct enetc_hw *hw = &pf->si->hw;
- int i, num_msix, total_si;
+ int num_si = pf->total_vfs + 1;
+ int i, num_msix;
u32 val;
- total_si = pf->caps.num_vsi + 1;
-
- num_msix = pf->caps.num_msix / total_si +
- pf->caps.num_msix % total_si - 1;
+ num_msix = pf->caps.num_msix / num_si +
+ pf->caps.num_msix % num_si - 1;
val = num_msix & PSICFGR2_NUM_MSIX;
enetc_port_wr(hw, ENETC4_PSICFGR2(0), val);
- num_msix = pf->caps.num_msix / total_si - 1;
+ num_msix = pf->caps.num_msix / num_si - 1;
val = num_msix & PSICFGR2_NUM_MSIX;
- for (i = 0; i < pf->caps.num_vsi; i++)
+ for (i = 0; i < pf->total_vfs; i++)
enetc_port_wr(hw, ENETC4_PSICFGR2(i + 1), val);
}
static void enetc4_enable_all_si(struct enetc_pf *pf)
{
struct enetc_hw *hw = &pf->si->hw;
- int num_si = pf->caps.num_vsi + 1;
+ int num_si = pf->total_vfs + 1;
u32 si_bitmap = 0;
int i;
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pf.h b/drivers/net/ethernet/freescale/enetc/enetc_pf.h
index 574ab4e76d8b..9c36ba50a7f0 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_pf.h
+++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.h
@@ -18,7 +18,6 @@ struct enetc_vf_state {
struct enetc_port_caps {
u32 half_duplex:1;
- int num_vsi;
int num_msix;
int num_rx_bdr;
int num_tx_bdr;
--
2.34.1
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH v2 net-next 13/14] net: enetc: use alloc_etherdev_mqs() to create netdev for VF driver
2026-07-02 2:57 [PATCH v2 net-next 00/14] net: enetc: cleanups and improvements wei.fang
` (11 preceding siblings ...)
2026-07-02 2:57 ` [PATCH v2 net-next 12/14] net: enetc: remove redundant num_vsi field from enetc_port_caps wei.fang
@ 2026-07-02 2:57 ` wei.fang
2026-07-03 3:27 ` sashiko-bot
2026-07-02 2:57 ` [PATCH v2 net-next 14/14] net: enetc: use kzalloc_flex() for enetc_psfp_gate allocation wei.fang
13 siblings, 1 reply; 25+ messages in thread
From: wei.fang @ 2026-07-02 2:57 UTC (permalink / raw)
To: claudiu.manoil, vladimir.oltean, xiaoning.wang, andrew+netdev,
davem, edumazet, kuba, pabeni, linux, wei.fang, chleroy
Cc: imx, netdev, linux-kernel, linuxppc-dev, linux-arm-kernel
From: Wei Fang <wei.fang@nxp.com>
The VF driver uses alloc_etherdev_mq() with ENETC_MAX_NUM_TXQS as the
queue count, which forces the TX and RX queue counts to be equal and
uses a compile-time constant rather than the actual hardware capability.
After enetc_get_si_caps() is called, si->num_tx_rings and
si->num_rx_rings reflect the actual number of rings assigned to the VF
by the PF. For the ENETC VF on LS1028A and the upcoming i.MX95/94, their
SoCs have no more than 6 CPUs, and the number of TX/RX rings allocated
to the VF is less than 8.
Therefore, switch to alloc_etherdev_mqs() so that the TX and RX queue
counts are set independently based on the real hardware values, avoiding
unnecessary queue structure allocation when the VF has fewer rings than
ENETC_MAX_NUM_TXQS.
Note that if future SoCs have more than 6 CPUs and more than 6 RX rings
allocated to VFs, the size of the int_vector array in struct
enetc_ndev_priv will need to be modified. Similarly, if more than 8 TX
rings are allocated to each int_vector, ENETC_MAX_NUM_TXQS will also
need to be modified.
Signed-off-by: Wei Fang <wei.fang@nxp.com>
---
drivers/net/ethernet/freescale/enetc/enetc_vf.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_vf.c b/drivers/net/ethernet/freescale/enetc/enetc_vf.c
index 9cdb0a4d6baf..3df515a6e333 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_vf.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc_vf.c
@@ -317,7 +317,8 @@ static int enetc_vf_probe(struct pci_dev *pdev,
enetc_get_si_caps(si);
- ndev = alloc_etherdev_mq(sizeof(*priv), ENETC_MAX_NUM_TXQS);
+ ndev = alloc_etherdev_mqs(sizeof(*priv), si->num_tx_rings,
+ si->num_rx_rings);
if (!ndev) {
err = -ENOMEM;
dev_err(&pdev->dev, "netdev creation failed\n");
--
2.34.1
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH v2 net-next 14/14] net: enetc: use kzalloc_flex() for enetc_psfp_gate allocation
2026-07-02 2:57 [PATCH v2 net-next 00/14] net: enetc: cleanups and improvements wei.fang
` (12 preceding siblings ...)
2026-07-02 2:57 ` [PATCH v2 net-next 13/14] net: enetc: use alloc_etherdev_mqs() to create netdev for VF driver wei.fang
@ 2026-07-02 2:57 ` wei.fang
2026-07-03 3:27 ` sashiko-bot
13 siblings, 1 reply; 25+ messages in thread
From: wei.fang @ 2026-07-02 2:57 UTC (permalink / raw)
To: claudiu.manoil, vladimir.oltean, xiaoning.wang, andrew+netdev,
davem, edumazet, kuba, pabeni, linux, wei.fang, chleroy
Cc: imx, netdev, linux-kernel, linuxppc-dev, linux-arm-kernel
From: Wei Fang <wei.fang@nxp.com>
Replace the open-coded struct_size() + kzalloc() pattern with the
kzalloc_flex() helper when allocating struct enetc_psfp_gate. This
removes the intermediate entries_size local variable and makes the
allocation site more concise.
Signed-off-by: Wei Fang <wei.fang@nxp.com>
---
drivers/net/ethernet/freescale/enetc/enetc_qos.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_qos.c b/drivers/net/ethernet/freescale/enetc/enetc_qos.c
index 7b17bca24f26..2aa0fcaafcd2 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_qos.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc_qos.c
@@ -1135,7 +1135,6 @@ static int enetc_psfp_parse_clsflower(struct enetc_ndev_priv *priv,
struct flow_action_entry *entry;
struct action_gate_entry *e;
u8 sfi_overwrite = 0;
- int entries_size;
int i, err;
if (f->common.chain_index >= priv->psfp_cap.max_streamid) {
@@ -1242,8 +1241,7 @@ static int enetc_psfp_parse_clsflower(struct enetc_ndev_priv *priv,
goto free_filter;
}
- entries_size = struct_size(sgi, entries, entryg->gate.num_entries);
- sgi = kzalloc(entries_size, GFP_KERNEL);
+ sgi = kzalloc_flex(*sgi, entries, entryg->gate.num_entries);
if (!sgi) {
err = -ENOMEM;
goto free_filter;
--
2.34.1
^ permalink raw reply related [flat|nested] 25+ messages in thread
* Re: [PATCH v2 net-next 07/14] net: enetc: differentiate phylink capabilities for pseudo-MAC and standalone MAC
2026-07-02 2:57 ` [PATCH v2 net-next 07/14] net: enetc: differentiate phylink capabilities for pseudo-MAC and standalone MAC wei.fang
@ 2026-07-02 17:30 ` Maxime Chevallier
2026-07-03 3:27 ` sashiko-bot
1 sibling, 0 replies; 25+ messages in thread
From: Maxime Chevallier @ 2026-07-02 17:30 UTC (permalink / raw)
To: wei.fang, claudiu.manoil, vladimir.oltean, xiaoning.wang,
andrew+netdev, davem, edumazet, kuba, pabeni, linux, wei.fang,
chleroy
Cc: imx, netdev, linux-kernel, linuxppc-dev, linux-arm-kernel
Hi,
On 7/2/26 04:57, wei.fang@oss.nxp.com wrote:
> From: Claudiu Manoil <claudiu.manoil@nxp.com>
>
> The ENETC pseudo-MACs are proprietary internal links that do not
> implement any standard MII interface, so restrict their supported PHY
> interface modes to PHY_INTERFACE_MODE_INTERNAL only.
>
> Since pseudo-MACs can operate at any speed between 10Mbps and 25Gbps
> in multiples of 10Mbps, set their MAC capabilities to cover the full
> range of standard full-duplex speeds: 10/100/1000/2500/5000/10000/
> 20000/25000 Mbps.
>
> For standalone ENETC, expand the supported interface modes to include
> 10GBASER and XGMII in addition to the existing RGMII, SGMII, 1000BASEX,
> 2500BASEX and USXGMII modes, with MAC capabilities up to 10G. MAC_1000
> is replaced with MAC_1000FD to explicitly exclude 1000M half-duplex,
> which is not supported.
>
> Signed-off-by: Claudiu Manoil <claudiu.manoil@nxp.com>
> Signed-off-by: Wei Fang <wei.fang@nxp.com>
Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
Maxime
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH v2 net-next 06/14] net: enetc: simplify enetc4_set_port_speed()
2026-07-02 2:57 ` [PATCH v2 net-next 06/14] net: enetc: simplify enetc4_set_port_speed() wei.fang
@ 2026-07-02 17:32 ` Maxime Chevallier
2026-07-03 3:27 ` sashiko-bot
1 sibling, 0 replies; 25+ messages in thread
From: Maxime Chevallier @ 2026-07-02 17:32 UTC (permalink / raw)
To: wei.fang, claudiu.manoil, vladimir.oltean, xiaoning.wang,
andrew+netdev, davem, edumazet, kuba, pabeni, linux, wei.fang,
chleroy
Cc: imx, netdev, linux-kernel, linuxppc-dev, linux-arm-kernel
On 7/2/26 04:57, wei.fang@oss.nxp.com wrote:
> From: Wei Fang <wei.fang@nxp.com>
>
> Since phylink only passes valid speed values to mac_link_up, the switch
> statement with its default fallback to SPEED_10 is unnecessary. Replace
> it with a direct call to PCR_PSPEED_VAL(). Also update PCR_PSPEED_VAL()
> to use FIELD_PREP() for proper field masking instead of an open-coded
> shift.
>
> Signed-off-by: Wei Fang <wei.fang@nxp.com>
Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
Maxime
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH v2 net-next 08/14] net: enetc: remove invalid code from enetc4_pl_mac_link_up()
2026-07-02 2:57 ` [PATCH v2 net-next 08/14] net: enetc: remove invalid code from enetc4_pl_mac_link_up() wei.fang
@ 2026-07-02 17:35 ` Maxime Chevallier
0 siblings, 0 replies; 25+ messages in thread
From: Maxime Chevallier @ 2026-07-02 17:35 UTC (permalink / raw)
To: wei.fang, claudiu.manoil, vladimir.oltean, xiaoning.wang,
andrew+netdev, davem, edumazet, kuba, pabeni, linux, wei.fang,
chleroy
Cc: imx, netdev, linux-kernel, linuxppc-dev, linux-arm-kernel
On 7/2/26 04:57, wei.fang@oss.nxp.com wrote:
> From: Wei Fang <wei.fang@nxp.com>
>
> When adding phylink MAC operations support to the NETC switch driver,
> Russell King pointed out several pieces of invalid logic in the
> .mac_link_up() implementation (see [1] and [2]):
>
> 1) Half-duplex backpressure is not supported by the kernel, Ethernet
> relies on packet dropping for congestion management.
>
> 2) phylink_autoneg_inband() is unnecessary, as RGMII in-band status is
> not supported.
>
> 3) TX and RX pause are disabled in half-duplex mode, so there is no
> need to override them in .mac_link_up().
>
> The same invalid logic is also present in enetc4_pl_mac_link_up(), so
> remove the invalid code from it.
>
> Link: https://lore.kernel.org/imx/acEIQqI-_oyCym8O@shell.armlinux.org.uk/ # 1
> Link: https://lore.kernel.org/imx/acEFwqmAvWls_9Ef@shell.armlinux.org.uk/ # 2
> Signed-off-by: Wei Fang <wei.fang@nxp.com>
Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
Maxime
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH v2 net-next 02/14] net: enetc: extract common helpers for MAC hash filter configuration
2026-07-02 2:57 ` [PATCH v2 net-next 02/14] net: enetc: extract common helpers for MAC hash filter configuration wei.fang
@ 2026-07-03 3:27 ` sashiko-bot
2026-07-03 7:02 ` Wei Fang (OSS)
0 siblings, 1 reply; 25+ messages in thread
From: sashiko-bot @ 2026-07-03 3:27 UTC (permalink / raw)
To: wei.fang; +Cc: imx, Frank.Li
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Pre-existing issues:
- [High] Pre-existing logic bug: Fallback to hash-based filtering fails for exact match (EM) MAC addresses because the hash table is not populated.
--
commit 0373b31ab4e7a0beb8461d5ceb05e09d7d5b61ab
Author: Wei Fang <wei.fang@nxp.com>
Date: Thu Jul 2 02:57:02 2026 +0000
net: enetc: extract common helpers for MAC hash filter configuration
The patch extracts enetc_set_si_uc_hash_filter() and
enetc_set_si_mc_hash_filter() into enetc_pf_common.c. This allows sharing
the MAC hash filter configuration between ENETC v1 and v4 drivers, and
removes redundant hardware-specific functions.
> diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pf.c b/drivers/net/ethernet/freescale/enetc/enetc_pf.c
> index a97d2e2dd07b7..db2a800a7aaf0 100644
> --- a/drivers/net/ethernet/freescale/enetc/enetc_pf.c
> +++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.c
[ ... ]
> @@ -135,7 +108,7 @@ static void enetc_sync_mac_filters(struct enetc_pf *pf)
> if (em) {
> int err;
>
> - enetc_clear_mac_ht_flt(si, 0, UC);
> + enetc_set_si_uc_hash_filter(si, 0, 0);
>
> err = enetc_set_mac_flt_entry(si, pos, f->mac_addr,
> BIT(0));
> @@ -147,11 +120,15 @@ static void enetc_sync_mac_filters(struct enetc_pf *pf)
> err);
> }
>
> + bitmap_to_arr64(&hash, f->mac_hash_table,
> + ENETC_MADDR_HASH_TBL_SZ);
> /* hash table filter, clear EM filter for UC entries */
> - if (i == UC)
> + if (i == UC) {
> enetc_clear_mac_flt_entry(si, pos);
> -
> - enetc_set_mac_ht_flt(si, 0, i, *f->mac_hash_table);
> + enetc_set_si_uc_hash_filter(si, 0, hash);
[Severity: High]
This is a pre-existing issue, but does this fallback path actually work for
exact match MAC addresses?
In enetc_pf_set_rx_mode(), when configuring a single unicast MAC address,
enetc_add_mac_addr_em_filter() is called, but the hash table population is
explicitly skipped:
enetc_pf_set_rx_mode() {
...
em = (netdev_uc_count(ndev) == 1);
netdev_for_each_uc_addr(ha, ndev) {
if (em) {
enetc_add_mac_addr_em_filter(filter, ha->addr);
break;
}
enetc_add_mac_addr_ht_filter(filter, ha->addr);
}
...
}
Because of this, mac_hash_table remains empty for the EM filter.
If enetc_set_mac_flt_entry() fails in enetc_sync_mac_filters(), the driver
warns "fallback to HT filt" and falls through to this block. However, since
the hash table was never populated, the derived hash is 0.
Doesn't this result in programming an empty hash filter, which will silently
drop all packets for this intended MAC address instead of falling back to
hash-based filtering?
> + } else {
> + enetc_set_si_mc_hash_filter(si, 0, hash);
> + }
> }
> }
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260702025714.456233-1-wei.fang@oss.nxp.com?part=2
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH v2 net-next 06/14] net: enetc: simplify enetc4_set_port_speed()
2026-07-02 2:57 ` [PATCH v2 net-next 06/14] net: enetc: simplify enetc4_set_port_speed() wei.fang
2026-07-02 17:32 ` Maxime Chevallier
@ 2026-07-03 3:27 ` sashiko-bot
1 sibling, 0 replies; 25+ messages in thread
From: sashiko-bot @ 2026-07-03 3:27 UTC (permalink / raw)
To: wei.fang; +Cc: Frank.Li, imx
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] Removal of the switch statement allows SPEED_UNKNOWN to be programmed as an invalid hardware state.
--
commit 923303ff32884703a5eb3f948098684f15149ba1
Author: Wei Fang <wei.fang@nxp.com>
net: enetc: simplify enetc4_set_port_speed()
This commit simplifies enetc4_set_port_speed() by removing a switch
statement, assuming phylink only passes valid speed values. It also
updates PCR_PSPEED_VAL() to use FIELD_PREP() instead of an open-coded
shift.
> diff --git a/drivers/net/ethernet/freescale/enetc/enetc4_hw.h b/drivers/net/ethernet/freescale/enetc/enetc4_hw.h
> index 6a8f2ed56017c..dea1fd0b81758 100644
> --- a/drivers/net/ethernet/freescale/enetc/enetc4_hw.h
> +++ b/drivers/net/ethernet/freescale/enetc/enetc4_hw.h
> @@ -148,7 +148,7 @@
> #define PCR_L2DOSE BIT(4)
> #define PCR_TIMER_CS BIT(8)
> #define PCR_PSPEED GENMASK(29, 16)
> -#define PCR_PSPEED_VAL(speed) (((speed) / 10 - 1) << 16)
> +#define PCR_PSPEED_VAL(s) FIELD_PREP(PCR_PSPEED, ((s) / 10 - 1))
[Severity: High]
Does this safely handle negative values like SPEED_UNKNOWN?
If SPEED_UNKNOWN (-1) is passed here, the expression ((s) / 10 - 1)
evaluates to -1. FIELD_PREP then casts this to an unsigned type and masks
it against PCR_PSPEED, filling all 14 bits with 1s (0x3FFF).
>
> /* Port MAC address register 0/1 */
> #define ENETC4_PMAR0 0x4020
> diff --git a/drivers/net/ethernet/freescale/enetc/enetc4_pf.c b/drivers/net/ethernet/freescale/enetc/enetc4_pf.c
> index b966637572a7a..db7bad2c3cbde 100644
> --- a/drivers/net/ethernet/freescale/enetc/enetc4_pf.c
> +++ b/drivers/net/ethernet/freescale/enetc/enetc4_pf.c
[ ... ]
> - switch (speed) {
> - case SPEED_100:
> - case SPEED_1000:
> - case SPEED_2500:
> - case SPEED_10000:
> - val |= (PCR_PSPEED & PCR_PSPEED_VAL(speed));
> - break;
> - case SPEED_10:
> - default:
> - val |= (PCR_PSPEED & PCR_PSPEED_VAL(SPEED_10));
> - }
> -
> - priv->speed = speed;
> + val = enetc_port_rd(&priv->si->hw, ENETC4_PCR) & (~PCR_PSPEED);
> + val |= PCR_PSPEED_VAL(speed);
[Severity: High]
The commit message states: "Since phylink only passes valid speed values
to mac_link_up, the switch statement with its default fallback to SPEED_10
is unnecessary."
Is this assumption accurate?
In the kernel phylib/phylink implementation, if a PHY establishes link before
autonegotiation completes (or if an out-of-band PCS status hasn't fully
resolved the speed), genphy_read_status() can leave phydev->speed as
SPEED_UNKNOWN (-1) while phydev->link is 1.
Phylink then propagates this state via phylink_resolve() and calls
mac_link_up() with SPEED_UNKNOWN.
Without the switch statement's default case, won't this write the 0x3FFF
garbage value generated by PCR_PSPEED_VAL() to the MAC speed configuration
register (ENETC4_PCR) and cause undefined hardware behavior?
> enetc_port_wr(&priv->si->hw, ENETC4_PCR, val);
> + priv->speed = speed;
> }
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260702025714.456233-1-wei.fang@oss.nxp.com?part=6
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH v2 net-next 07/14] net: enetc: differentiate phylink capabilities for pseudo-MAC and standalone MAC
2026-07-02 2:57 ` [PATCH v2 net-next 07/14] net: enetc: differentiate phylink capabilities for pseudo-MAC and standalone MAC wei.fang
2026-07-02 17:30 ` Maxime Chevallier
@ 2026-07-03 3:27 ` sashiko-bot
1 sibling, 0 replies; 25+ messages in thread
From: sashiko-bot @ 2026-07-03 3:27 UTC (permalink / raw)
To: wei.fang; +Cc: Frank.Li, imx
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] Adding PHY_INTERFACE_MODE_XGMII to enetc_port_has_pcs() erroneously associates a parallel interface with an internal PCS, breaking XGMII probe.
--
commit 0ce9c644ca0e73f4e3a24d681275147515f923ae
Author: Claudiu Manoil <claudiu.manoil@nxp.com>
net: enetc: differentiate phylink capabilities for pseudo-MAC and standalone MAC
This commit separates phylink capabilities for ENETC pseudo-MACs and
standalone MACs. It restricts pseudo-MACs to internal modes and expands
standalone MACs to support additional interfaces like 10GBASER and XGMII.
[ ... ]
> diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pf_common.c b/drivers/net/ethernet/freescale/enetc/enetc_pf_common.c
> index 3597cb81a7ccb..6ccf9b9090549 100644
> --- a/drivers/net/ethernet/freescale/enetc/enetc_pf_common.c
> +++ b/drivers/net/ethernet/freescale/enetc/enetc_pf_common.c
[ ... ]
> @@ -359,7 +359,9 @@ static bool enetc_port_has_pcs(struct enetc_pf *pf)
> return (pf->if_mode == PHY_INTERFACE_MODE_SGMII ||
> pf->if_mode == PHY_INTERFACE_MODE_1000BASEX ||
> pf->if_mode == PHY_INTERFACE_MODE_2500BASEX ||
> - pf->if_mode == PHY_INTERFACE_MODE_USXGMII);
> + pf->if_mode == PHY_INTERFACE_MODE_USXGMII ||
> + pf->if_mode == PHY_INTERFACE_MODE_10GBASER ||
> + pf->if_mode == PHY_INTERFACE_MODE_XGMII);
[Severity: High]
Does adding XGMII here cause probe failures for ENETC v4 devices?
XGMII is a direct parallel MAC-to-PHY interface that fundamentally does not
use a PCS. If enetc_port_has_pcs() returns true for XGMII,
enetc_mdiobus_create() will attempt to create an internal PCS via
enetc_imdio_create().
Since the ENETC v4 .create_pcs callback is NULL, enetc_imdio_create() will
unconditionally fail and return -EOPNOTSUPP, preventing initialization when
configured with phy-mode = "xgmii".
Should PHY_INTERFACE_MODE_XGMII be excluded from this check so it can bypass
PCS initialization and allow phylink to configure the link based purely on
MAC capabilities?
[ ... ]
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260702025714.456233-1-wei.fang@oss.nxp.com?part=7
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH v2 net-next 10/14] net: enetc: refactor SI VLAN promiscuous mode configuration
2026-07-02 2:57 ` [PATCH v2 net-next 10/14] net: enetc: refactor SI VLAN promiscuous mode configuration wei.fang
@ 2026-07-03 3:27 ` sashiko-bot
0 siblings, 0 replies; 25+ messages in thread
From: sashiko-bot @ 2026-07-03 3:27 UTC (permalink / raw)
To: wei.fang; +Cc: imx, Frank.Li
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] Removing explicit initialization of VLAN promiscuous mode leaves hardware and software out of sync if PCI FLR fails or is bypassed.
--
commit e4ae080b51f21aa8943d5f438c5a46ac35824f4b
Author: Wei Fang <wei.fang@nxp.com>
Subject: net: enetc: refactor SI VLAN promiscuous mode configuration
This commit refactors the VLAN promiscuous mode configuration in the enetc
driver. It removes explicit initialization of VLAN promiscuous mode during
port configuration, relying instead on the PCI FLR default state, and
introduces a unified function for setting SI VLAN promiscuous mode.
> diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pf.c b/drivers/net/ethernet/freescale/enetc/enetc_pf.c
> index db2a800a7aaf0..096ccb35508c5 100644
> --- a/drivers/net/ethernet/freescale/enetc/enetc_pf.c
> +++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.c
[ ... ]
> @@ -442,10 +438,6 @@ static void enetc_configure_port(struct enetc_pf *pf)
> /* split up RFS entries */
> enetc_port_assign_rfs_entries(pf->si);
>
> - /* enforce VLAN promisc mode for all SIs */
> - pf->vlan_promisc_simap = ENETC_VLAN_PROMISC_MAP_ALL;
> - enetc_set_vlan_promisc(hw, pf->vlan_promisc_simap);
> -
> enetc_port_wr(hw, ENETC_PSIPMMR, 0);
[Severity: High]
Is it safe to rely solely on PCI FLR for VLAN promiscuous mode initialization
here in enetc_configure_port()?
If the PF driver is reloaded, or the kernel is warm-booted (e.g., via kexec)
and PCI FLR fails or is disabled (e.g., via pci=noflr), the hardware's VLAN
promiscuous mode register (ENETC_PSIPVMR) will retain its previous state.
If VLAN filtering was previously enabled, could the hardware silently drop
VLAN-tagged packets while the software assumes they are accepted?
Because NETIF_F_HW_VLAN_CTAG_FILTER is not enabled by default in
ndev->features, the core network stack will not invoke enetc_pf_set_features()
during registration to sync the software state with the hardware.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260702025714.456233-1-wei.fang@oss.nxp.com?part=10
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH v2 net-next 13/14] net: enetc: use alloc_etherdev_mqs() to create netdev for VF driver
2026-07-02 2:57 ` [PATCH v2 net-next 13/14] net: enetc: use alloc_etherdev_mqs() to create netdev for VF driver wei.fang
@ 2026-07-03 3:27 ` sashiko-bot
0 siblings, 0 replies; 25+ messages in thread
From: sashiko-bot @ 2026-07-03 3:27 UTC (permalink / raw)
To: wei.fang; +Cc: Frank.Li, imx
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] Dynamically allocating netdev queues based on unvalidated hardware ring counts bypasses previous implicit limits, leading to array overflows and unhandled interrupts (interrupt storms) for queues >= 8.
--
commit 25e82eb7e0ae74aa61ceb3d3b3628db74277e9eb
Author: Wei Fang <wei.fang@nxp.com>
net: enetc: use alloc_etherdev_mqs() to create netdev for VF driver
The VF driver currently uses alloc_etherdev_mq() with a fixed queue count.
This commit changes it to use alloc_etherdev_mqs() so that TX and RX queue
counts can be set independently based on actual hardware capabilities.
> diff --git a/drivers/net/ethernet/freescale/enetc/enetc_vf.c b/drivers/net/ethernet/freescale/enetc/enetc_vf.c
> index 9cdb0a4d6bafb..3df515a6e3335 100644
> --- a/drivers/net/ethernet/freescale/enetc/enetc_vf.c
> +++ b/drivers/net/ethernet/freescale/enetc/enetc_vf.c
> @@ -317,7 +317,8 @@ static int enetc_vf_probe(struct pci_dev *pdev,
>
> enetc_get_si_caps(si);
>
> - ndev = alloc_etherdev_mq(sizeof(*priv), ENETC_MAX_NUM_TXQS);
> + ndev = alloc_etherdev_mqs(sizeof(*priv), si->num_tx_rings,
> + si->num_rx_rings);
[Severity: High]
By dynamically allocating the netdev queues based on unvalidated hardware
ring counts, can this bypass previous limits and cause array overflows?
Previously, alloc_etherdev_mq() capped the queue allocation to
ENETC_MAX_NUM_TXQS, which safely bounded the number of queues and would fail
if the hardware capabilities were excessive. If a PF or hypervisor
configures the VF with excessive queues (for instance, si->num_tx_rings > 8
or si->num_rx_rings > 6), wouldn't this allocation now succeed and lead to
out-of-bounds writes during initialization?
For example, in enetc_int_vector_init():
drivers/net/ethernet/freescale/enetc/enetc.c:enetc_int_vector_init() {
...
priv->int_vector[i] = v;
...
priv->tx_ring[idx] = bdr;
...
}
If si->num_rx_rings > 6 and num_online_cpus() > 6, doesn't this overflow
the priv->int_vector[] array? And if si->num_tx_rings > 16, won't this
overflow the fixed 16-element priv->tx_ring[] array?
Furthermore, for TX queues >= 8, it seems the MSI-X handler and NAPI poll
loop still use the hardcoded limit ENETC_MAX_NUM_TXQS (8):
drivers/net/ethernet/freescale/enetc/enetc.c:enetc_msix() {
...
for_each_set_bit(i, &v->tx_rings_map, ENETC_MAX_NUM_TXQS)
...
}
And similarly in enetc_poll():
drivers/net/ethernet/freescale/enetc/enetc.c:enetc_poll() {
...
for_each_set_bit(i, &v->tx_rings_map, ENETC_MAX_NUM_TXQS)
...
}
Will this fail to clear or re-enable interrupts for TX queues >= 8,
resulting in unhandled interrupts and an immediate system lockup?
Should we validate si->num_tx_rings and si->num_rx_rings against the
maximum sizes supported by the driver structures before allocating the
netdev?
> if (!ndev) {
> err = -ENOMEM;
> dev_err(&pdev->dev, "netdev creation failed\n");
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260702025714.456233-1-wei.fang@oss.nxp.com?part=13
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH v2 net-next 14/14] net: enetc: use kzalloc_flex() for enetc_psfp_gate allocation
2026-07-02 2:57 ` [PATCH v2 net-next 14/14] net: enetc: use kzalloc_flex() for enetc_psfp_gate allocation wei.fang
@ 2026-07-03 3:27 ` sashiko-bot
0 siblings, 0 replies; 25+ messages in thread
From: sashiko-bot @ 2026-07-03 3:27 UTC (permalink / raw)
To: wei.fang; +Cc: Frank.Li, imx
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Pre-existing issues:
- [High] Hardware data buffers for Stream Gate Control List (sgcl_data) and Stream Filter Counters (sfi_counter_data) use native u32 fields without cpu_to_le32() / le32_to_cpu() conversions.
--
commit e19bf50d7194e9cfc29fbcd1560a65dbc9d0f7a0
Author: Wei Fang <wei.fang@nxp.com>
net: enetc: use kzalloc_flex() for enetc_psfp_gate allocation
Replace the open-coded struct_size() + kzalloc() pattern with the
kzalloc_flex() helper when allocating struct enetc_psfp_gate. This
removes the intermediate entries_size local variable and makes the
allocation site more concise.
> diff --git a/drivers/net/ethernet/freescale/enetc/enetc_qos.c b/drivers/net/ethernet/freescale/enetc/enetc_qos.c
> index 7b17bca24f260..2aa0fcaafcd23 100644
> --- a/drivers/net/ethernet/freescale/enetc/enetc_qos.c
> +++ b/drivers/net/ethernet/freescale/enetc/enetc_qos.c
[ ... ]
> @@ -1242,8 +1241,7 @@ static int enetc_psfp_parse_clsflower(struct enetc_ndev_priv *priv,
> goto free_filter;
> }
>
> - entries_size = struct_size(sgi, entries, entryg->gate.num_entries);
> - sgi = kzalloc(entries_size, GFP_KERNEL);
> + sgi = kzalloc_flex(*sgi, entries, entryg->gate.num_entries);
[Severity: High]
This isn't a bug introduced by this patch, but does the hardware data buffer
for the Stream Gate Control List (sgcl_data) and Stream Filter Counters
(sfi_counter_data) need cpu_to_le32() / le32_to_cpu() conversions?
In enetc_streamgate_hw_set(), native u32 values are written into the
sgcl_data structure without endianness conversion:
sgcl_data->ct = sgi->cycletime;
sgcl_data->cte = sgi->cycletimext;
and later for the entries:
to->interval = from->interval;
Similarly, in enetc_streamcounter_hw_get(), native u32 values are read from
the sfi_counter_data structure:
cnt->matching_frames_count = ((u64)data_buf->matchh << 32) +
data_buf->matchl;
Since these structures are mapped to hardware via coherent DMA memory, will
this cause the hardware to receive incorrect configuration values and software
to read corrupted QoS statistics on Big Endian architectures?
> if (!sgi) {
> err = -ENOMEM;
> goto free_filter;
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260702025714.456233-1-wei.fang@oss.nxp.com?part=14
^ permalink raw reply [flat|nested] 25+ messages in thread
* RE: [PATCH v2 net-next 02/14] net: enetc: extract common helpers for MAC hash filter configuration
2026-07-03 3:27 ` sashiko-bot
@ 2026-07-03 7:02 ` Wei Fang (OSS)
0 siblings, 0 replies; 25+ messages in thread
From: Wei Fang (OSS) @ 2026-07-03 7:02 UTC (permalink / raw)
To: sashiko-reviews@lists.linux.dev
Cc: imx@lists.linux.dev, Frank.Li@kernel.org, network dev
> commit 0373b31ab4e7a0beb8461d5ceb05e09d7d5b61ab
> Author: Wei Fang <wei.fang@nxp.com>
> Date: Thu Jul 2 02:57:02 2026 +0000
>
> net: enetc: extract common helpers for MAC hash filter configuration
>
> The patch extracts enetc_set_si_uc_hash_filter() and
> enetc_set_si_mc_hash_filter() into enetc_pf_common.c. This allows sharing
> the MAC hash filter configuration between ENETC v1 and v4 drivers, and
> removes redundant hardware-specific functions.
>
> > diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pf.c
> b/drivers/net/ethernet/freescale/enetc/enetc_pf.c
> > index a97d2e2dd07b7..db2a800a7aaf0 100644
> > --- a/drivers/net/ethernet/freescale/enetc/enetc_pf.c
> > +++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.c
> [ ... ]
> > @@ -135,7 +108,7 @@ static void enetc_sync_mac_filters(struct enetc_pf
> *pf)
> > if (em) {
> > int err;
> >
> > - enetc_clear_mac_ht_flt(si, 0, UC);
> > + enetc_set_si_uc_hash_filter(si, 0, 0);
> >
> > err = enetc_set_mac_flt_entry(si, pos, f->mac_addr,
> > BIT(0));
> > @@ -147,11 +120,15 @@ static void enetc_sync_mac_filters(struct enetc_pf
> *pf)
> > err);
> > }
> >
> > + bitmap_to_arr64(&hash, f->mac_hash_table,
> > + ENETC_MADDR_HASH_TBL_SZ);
> > /* hash table filter, clear EM filter for UC entries */
> > - if (i == UC)
> > + if (i == UC) {
> > enetc_clear_mac_flt_entry(si, pos);
> > -
> > - enetc_set_mac_ht_flt(si, 0, i, *f->mac_hash_table);
> > + enetc_set_si_uc_hash_filter(si, 0, hash);
>
> [Severity: High]
> This is a pre-existing issue, but does this fallback path actually work for
> exact match MAC addresses?
>
> In enetc_pf_set_rx_mode(), when configuring a single unicast MAC address,
> enetc_add_mac_addr_em_filter() is called, but the hash table population is
> explicitly skipped:
>
> enetc_pf_set_rx_mode() {
> ...
> em = (netdev_uc_count(ndev) == 1);
> netdev_for_each_uc_addr(ha, ndev) {
> if (em) {
> enetc_add_mac_addr_em_filter(filter, ha->addr);
> break;
> }
> enetc_add_mac_addr_ht_filter(filter, ha->addr);
> }
> ...
> }
>
> Because of this, mac_hash_table remains empty for the EM filter.
>
> If enetc_set_mac_flt_entry() fails in enetc_sync_mac_filters(), the driver
> warns "fallback to HT filt" and falls through to this block. However, since
> the hash table was never populated, the derived hash is 0.
>
> Doesn't this result in programming an empty hash filter, which will silently
> drop all packets for this intended MAC address instead of falling back to
> hash-based filtering?
>
Yes, the code behavior is inconsistent with the comments, and this issue
will be resolved by adding a fix patch. The current patch does not require
modification.
^ permalink raw reply [flat|nested] 25+ messages in thread
end of thread, other threads:[~2026-07-03 7:02 UTC | newest]
Thread overview: 25+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-02 2:57 [PATCH v2 net-next 00/14] net: enetc: cleanups and improvements wei.fang
2026-07-02 2:57 ` [PATCH v2 net-next 01/14] net: enetc: extract common helpers for MAC promiscuous mode setting wei.fang
2026-07-02 2:57 ` [PATCH v2 net-next 02/14] net: enetc: extract common helpers for MAC hash filter configuration wei.fang
2026-07-03 3:27 ` sashiko-bot
2026-07-03 7:02 ` Wei Fang (OSS)
2026-07-02 2:57 ` [PATCH v2 net-next 03/14] net: enetc: convert ndo_set_rx_mode() to ndo_set_rx_mode_async() wei.fang
2026-07-02 2:57 ` [PATCH v2 net-next 04/14] net: enetc: improve MAFT entry management with bitmap tracking wei.fang
2026-07-02 2:57 ` [PATCH v2 net-next 05/14] net: enetc: use PCI device name for debugfs directory wei.fang
2026-07-02 2:57 ` [PATCH v2 net-next 06/14] net: enetc: simplify enetc4_set_port_speed() wei.fang
2026-07-02 17:32 ` Maxime Chevallier
2026-07-03 3:27 ` sashiko-bot
2026-07-02 2:57 ` [PATCH v2 net-next 07/14] net: enetc: differentiate phylink capabilities for pseudo-MAC and standalone MAC wei.fang
2026-07-02 17:30 ` Maxime Chevallier
2026-07-03 3:27 ` sashiko-bot
2026-07-02 2:57 ` [PATCH v2 net-next 08/14] net: enetc: remove invalid code from enetc4_pl_mac_link_up() wei.fang
2026-07-02 17:35 ` Maxime Chevallier
2026-07-02 2:57 ` [PATCH v2 net-next 09/14] net: enetc: remove enetc4_set_default_si_vlan_promisc() wei.fang
2026-07-02 2:57 ` [PATCH v2 net-next 10/14] net: enetc: refactor SI VLAN promiscuous mode configuration wei.fang
2026-07-03 3:27 ` sashiko-bot
2026-07-02 2:57 ` [PATCH v2 net-next 11/14] net: enetc: move enetc_set_si_vlan_promisc() to enetc_pf_common.c wei.fang
2026-07-02 2:57 ` [PATCH v2 net-next 12/14] net: enetc: remove redundant num_vsi field from enetc_port_caps wei.fang
2026-07-02 2:57 ` [PATCH v2 net-next 13/14] net: enetc: use alloc_etherdev_mqs() to create netdev for VF driver wei.fang
2026-07-03 3:27 ` sashiko-bot
2026-07-02 2:57 ` [PATCH v2 net-next 14/14] net: enetc: use kzalloc_flex() for enetc_psfp_gate allocation wei.fang
2026-07-03 3:27 ` sashiko-bot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox