diff options
| author | Serge Semin <fancer.lancer@gmail.com> | 2025-03-25 21:50:49 +0300 |
|---|---|---|
| committer | Serge Semin <fancer.lancer@gmail.com> | 2026-08-13 20:34:12 +0300 |
| commit | 28b7ceecaa507209e6e7224241f253d0c6887f08 (patch) | |
| tree | 53da8fc48eb9fbc925bcb5ad71ada04f04dc72b0 | |
| parent | e0f507d2d6e578e7209a9796641b1bfa81bc6b72 (diff) | |
| download | linux-28b7ceecaa507209e6e7224241f253d0c6887f08.tar.gz linux-28b7ceecaa507209e6e7224241f253d0c6887f08.zip | |
net: stmmac: vlan: Fix VLAN filter basically disabled by default
If no Extended VLAN filter Filtering supported, then a basic perfect
VLAN-filter will be available. That filter regards VID=0 as a special value
which if specified in the filter register basically means to accept any
VLAN frame irrespective to the hash-based VLAN-filter settings. Here is
the MAC_VLAN_Tag.VID field description actual for both DW QoS Eth and DW
XGMAC IP-cores:
> If this field ([11:0] if ETV is set) is all zeros, the MAC does not
> check the 15th and 16th bytes for VLAN tag comparison and
> declares all packets with Type field value of 0x8100 or 0x88a8
> as VLAN packets.
This is also documented by the table "VLAN Match Status" in the IP-cores
databooks:
VID | VLAN Perfect Filter | VTHM | VLAN Hash Filter | Final VLAN |
| Match Result | Bit | Match Result | Match Status |
----+---------------------+------+------------------+--------------+
0 | Pass | 0 | Any | Pass |
0 | Pass | 1 | Any | Pass |
So in order to have the VLAN-filtering actually working for hardware with
no Extended VLAN filter support by default let's always initialize the
MAC_VLAN_Tag.VID with 0xffff's if no real VID specified. Thus no real VLAN
frames would be permitted except the packets with the reserved VID, which
is better than permitting all VIDs and making VLAN hash filter basically
useless.
Fixes: 3cd1cfcba26e ("net: stmmac: Implement VLAN Hash Filtering in XGMAC")
Fixes: ed64639bc1e0 ("net: stmmac: Add support for VLAN Rx filtering")
Signed-off-by: Serge Semin <fancer.lancer@gmail.com>
| -rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/stmmac_vlan.c | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_vlan.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_vlan.c index 1550843446a7..7f1e34e62eee 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_vlan.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_vlan.c @@ -13,6 +13,8 @@ static void vlan_write_single(struct net_device *dev, u32 data) u32 val, mask; mask = VLAN_TAG_ERSVLM | VLAN_TAG_VID; + if (!(data & VLAN_TAG_VID)) + data |= VLAN_TAG_VID; val = readl(ioaddr + VLAN_TAG) & ~mask; val |= VLAN_TAG_ETV | (data & mask); @@ -209,6 +211,9 @@ static void vlan_update_hash(struct mac_device_info *hw, u32 hash, value &= ~VLAN_DOVLTC; } + if (!hw->vlan_filter[0]) + value |= VLAN_VID; + writel(value, ioaddr + VLAN_TAG); } else if (perfect_match) { u32 value = VLAN_ETV; @@ -228,7 +233,8 @@ static void vlan_update_hash(struct mac_device_info *hw, u32 hash, value &= ~(VLAN_VTHM | VLAN_ETV); value &= ~(VLAN_EDVLP | VLAN_ESVL); value &= ~VLAN_DOVLTC; - value &= ~VLAN_VID; + if (!hw->vlan_filter[0]) + value |= VLAN_VID; writel(value, ioaddr + VLAN_TAG); } @@ -298,7 +304,9 @@ static void dwxgmac2_update_vlan_hash(struct mac_device_info *hw, u32 hash, value &= ~VLAN_DOVLTC; } - value &= ~VLAN_VID; + if (!hw->vlan_filter[0]) + value |= VLAN_VID; + writel(value, ioaddr + VLAN_TAG); } else if (perfect_match) { value &= ~VLAN_VTHM; @@ -319,7 +327,8 @@ static void dwxgmac2_update_vlan_hash(struct mac_device_info *hw, u32 hash, value &= ~(VLAN_VTHM | VLAN_ETV); value &= ~(VLAN_EDVLP | VLAN_ESVL); value &= ~VLAN_DOVLTC; - value &= ~VLAN_VID; + if (!hw->vlan_filter[0]) + value |= VLAN_VID; writel(value, ioaddr + VLAN_TAG); } |
