diff options
| author | Serge Semin <fancer.lancer@gmail.com> | 2025-04-16 21:01:02 +0300 |
|---|---|---|
| committer | Serge Semin <fancer.lancer@gmail.com> | 2026-08-13 20:34:12 +0300 |
| commit | d6cd34229a19ff94da813d53bc5845748a590f22 (patch) | |
| tree | fc6b03098ca09796985efa83913ef4205de5f71d | |
| parent | 28b7ceecaa507209e6e7224241f253d0c6887f08 (diff) | |
| download | linux-d6cd34229a19ff94da813d53bc5845748a590f22.tar.gz linux-d6cd34229a19ff94da813d53bc5845748a590f22.zip | |
net: stmmac: vlan: Fix VLAN_TAG register override on perfect-match
The stmmac_vlan_update() method falls back to the basic perfect filter
case if no VLAN hash filter detected. In that case the method completely
overrides the VLAN_TAG register clearing the settings like EVLRXS or EVLS,
which are required for the VLAN interface to work correctly. For instance
EVLRXS activates VLAN Tag in Rx status getting the Rx DMA-descriptors.
So let's fix that in a way it has been done for DW XGMAC VLAN in commit
907a076881f1 ("net: stmmac: xgmac: fix incorrect XGMAC_VLAN_TAG register
writting") - by using the already read value of the VLAN_TAG register.
Fixes: c7ab0b8088d7 ("net: stmmac: Fallback to VLAN Perfect filtering if HASH is not available")
Signed-off-by: Serge Semin <fancer.lancer@gmail.com>
| -rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/stmmac_vlan.c | 5 |
1 files changed, 3 insertions, 2 deletions
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_vlan.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_vlan.c index 7f1e34e62eee..c553cf6b772e 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_vlan.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_vlan.c @@ -216,8 +216,8 @@ static void vlan_update_hash(struct mac_device_info *hw, u32 hash, writel(value, ioaddr + VLAN_TAG); } else if (perfect_match) { - u32 value = VLAN_ETV; - + value &= ~VLAN_VTHM; + value |= VLAN_ETV; if (is_double) { value |= VLAN_EDVLP; value |= VLAN_ESVL; @@ -228,6 +228,7 @@ static void vlan_update_hash(struct mac_device_info *hw, u32 hash, value &= ~VLAN_DOVLTC; } + value &= ~VLAN_VID; writel(value | perfect_match, ioaddr + VLAN_TAG); } else { value &= ~(VLAN_VTHM | VLAN_ETV); |
