mirror of
https://github.com/torvalds/linux.git
synced 2026-03-08 03:04:51 +01:00
net: stmmac: Fix error handling in VLAN add and delete paths
stmmac_vlan_rx_add_vid() updates active_vlans and the VLAN hash
register before writing the HW filter entry. If the filter write
fails, it leaves a stale VID in active_vlans and the hash register.
stmmac_vlan_rx_kill_vid() has the reverse problem: it clears
active_vlans before removing the HW filter. On failure, the VID is
gone from active_vlans but still present in the HW filter table.
To fix this, reorder the operations to update the hash table first,
then attempt the HW filter operation. If the HW filter fails, roll
back both the active_vlans bitmap and the hash table by calling
stmmac_vlan_update() again.
Fixes: ed64639bc1 ("net: stmmac: Add support for VLAN Rx filtering")
Signed-off-by: Ovidiu Panait <ovidiu.panait.rb@renesas.com>
Link: https://patch.msgid.link/20260303145828.7845-2-ovidiu.panait.rb@renesas.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
550921c67b
commit
35dfedce44
1 changed files with 14 additions and 4 deletions
|
|
@ -6794,9 +6794,13 @@ static int stmmac_vlan_rx_add_vid(struct net_device *ndev, __be16 proto, u16 vid
|
|||
|
||||
if (priv->hw->num_vlan) {
|
||||
ret = stmmac_add_hw_vlan_rx_fltr(priv, ndev, priv->hw, proto, vid);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
clear_bit(vid, priv->active_vlans);
|
||||
stmmac_vlan_update(priv, is_double);
|
||||
goto err_pm_put;
|
||||
}
|
||||
}
|
||||
|
||||
err_pm_put:
|
||||
pm_runtime_put(priv->device);
|
||||
|
||||
|
|
@ -6820,15 +6824,21 @@ static int stmmac_vlan_rx_kill_vid(struct net_device *ndev, __be16 proto, u16 vi
|
|||
is_double = true;
|
||||
|
||||
clear_bit(vid, priv->active_vlans);
|
||||
ret = stmmac_vlan_update(priv, is_double);
|
||||
if (ret) {
|
||||
set_bit(vid, priv->active_vlans);
|
||||
goto del_vlan_error;
|
||||
}
|
||||
|
||||
if (priv->hw->num_vlan) {
|
||||
ret = stmmac_del_hw_vlan_rx_fltr(priv, ndev, priv->hw, proto, vid);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
set_bit(vid, priv->active_vlans);
|
||||
stmmac_vlan_update(priv, is_double);
|
||||
goto del_vlan_error;
|
||||
}
|
||||
}
|
||||
|
||||
ret = stmmac_vlan_update(priv, is_double);
|
||||
|
||||
del_vlan_error:
|
||||
pm_runtime_put(priv->device);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue