mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-14 02:59:19 -04:00
net: enetc: add VLAN filtering support for i.MX95 ENETC PF
Since the offsets of the VLAN hash filter registers of ENETC v4 are different from ENETC v1. Therefore, enetc_set_si_vlan_ht_filter() is added to set the correct VLAN hash filter based on the SI ID and ENETC revision, so that ENETC v4 PF driver can reuse enetc_vlan_rx_add_vid() and enetc_vlan_rx_del_vid(). In addition, the VLAN promiscuous mode will be enabled if VLAN filtering is disabled, which means that PF qualifies for reception of all VLAN tags. Signed-off-by: Wei Fang <wei.fang@nxp.com> Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com> Link: https://patch.msgid.link/20250506080735.3444381-14-wei.fang@nxp.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
@@ -107,6 +107,10 @@
|
||||
#define ENETC4_PSIMMHFR0(a) ((a) * 0x80 + 0x2058)
|
||||
#define ENETC4_PSIMMHFR1(a) ((a) * 0x80 + 0x205c)
|
||||
|
||||
/* Port station interface a VLAN hash filter register 0/1 */
|
||||
#define ENETC4_PSIVHFR0(a) ((a) * 0x80 + 0x2060)
|
||||
#define ENETC4_PSIVHFR1(a) ((a) * 0x80 + 0x2064)
|
||||
|
||||
#define ENETC4_PMCAPR 0x4004
|
||||
#define PMCAPR_HD BIT(8)
|
||||
#define PMCAPR_FP GENMASK(10, 9)
|
||||
|
||||
@@ -526,6 +526,16 @@ static void enetc4_pf_set_rx_mode(struct net_device *ndev)
|
||||
static int enetc4_pf_set_features(struct net_device *ndev,
|
||||
netdev_features_t features)
|
||||
{
|
||||
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_features(ndev, features);
|
||||
|
||||
return 0;
|
||||
@@ -539,6 +549,8 @@ static const struct net_device_ops enetc4_ndev_ops = {
|
||||
.ndo_set_mac_address = enetc_pf_set_mac_addr,
|
||||
.ndo_set_rx_mode = 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,
|
||||
};
|
||||
|
||||
static struct phylink_pcs *
|
||||
|
||||
@@ -135,7 +135,7 @@ void enetc_pf_netdev_setup(struct enetc_si *si, struct net_device *ndev,
|
||||
|
||||
/* TODO: currently, i.MX95 ENETC driver does not support advanced features */
|
||||
if (!is_enetc_rev1(si)) {
|
||||
ndev->hw_features &= ~(NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_LOOPBACK);
|
||||
ndev->hw_features &= ~NETIF_F_LOOPBACK;
|
||||
goto end;
|
||||
}
|
||||
|
||||
@@ -376,11 +376,22 @@ static void enetc_refresh_vlan_ht_filter(struct enetc_pf *pf)
|
||||
}
|
||||
}
|
||||
|
||||
static void enetc_set_vlan_ht_filter(struct enetc_hw *hw, int si_idx,
|
||||
unsigned long hash)
|
||||
static void enetc_set_si_vlan_ht_filter(struct enetc_si *si,
|
||||
int si_id, u64 hash)
|
||||
{
|
||||
enetc_port_wr(hw, ENETC_PSIVHFR0(si_idx), lower_32_bits(hash));
|
||||
enetc_port_wr(hw, ENETC_PSIVHFR1(si_idx), upper_32_bits(hash));
|
||||
struct enetc_hw *hw = &si->hw;
|
||||
int high_reg_off, low_reg_off;
|
||||
|
||||
if (is_enetc_rev1(si)) {
|
||||
low_reg_off = ENETC_PSIVHFR0(si_id);
|
||||
high_reg_off = ENETC_PSIVHFR1(si_id);
|
||||
} else {
|
||||
low_reg_off = ENETC4_PSIVHFR0(si_id);
|
||||
high_reg_off = ENETC4_PSIVHFR1(si_id);
|
||||
}
|
||||
|
||||
enetc_port_wr(hw, low_reg_off, lower_32_bits(hash));
|
||||
enetc_port_wr(hw, high_reg_off, upper_32_bits(hash));
|
||||
}
|
||||
|
||||
int enetc_vlan_rx_add_vid(struct net_device *ndev, __be16 prot, u16 vid)
|
||||
@@ -393,7 +404,7 @@ int enetc_vlan_rx_add_vid(struct net_device *ndev, __be16 prot, u16 vid)
|
||||
|
||||
idx = enetc_vid_hash_idx(vid);
|
||||
if (!__test_and_set_bit(idx, pf->vlan_ht_filter))
|
||||
enetc_set_vlan_ht_filter(&pf->si->hw, 0, *pf->vlan_ht_filter);
|
||||
enetc_set_si_vlan_ht_filter(pf->si, 0, *pf->vlan_ht_filter);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -406,7 +417,7 @@ int enetc_vlan_rx_del_vid(struct net_device *ndev, __be16 prot, u16 vid)
|
||||
|
||||
if (__test_and_clear_bit(vid, pf->active_vlans)) {
|
||||
enetc_refresh_vlan_ht_filter(pf);
|
||||
enetc_set_vlan_ht_filter(&pf->si->hw, 0, *pf->vlan_ht_filter);
|
||||
enetc_set_si_vlan_ht_filter(pf->si, 0, *pf->vlan_ht_filter);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
Reference in New Issue
Block a user