summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSerge Semin <fancer.lancer@gmail.com>2025-03-25 21:50:49 +0300
committerSerge Semin <fancer.lancer@gmail.com>2026-08-13 20:34:12 +0300
commit28b7ceecaa507209e6e7224241f253d0c6887f08 (patch)
tree53da8fc48eb9fbc925bcb5ad71ada04f04dc72b0
parente0f507d2d6e578e7209a9796641b1bfa81bc6b72 (diff)
downloadlinux-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.c15
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);
}