Currently, the EDVLP bit is toggled whenever an 802.1ad VLAN is
registered. This bit enables the double VLAN feature, which provides
a way to insert, extract and filter an additional inner VLAN tag, and
has nothing to do with S-Tag handling.

Move EDVLP handling into vlan_set_hw_mode() instead, and keep it always
enabled, so that COE can work for packets with an inner VLAN header.
Add a dedicated callback for dwxlgmac2, as it doesn't implement the
set_hw_vlan_mode callback, like the other cores.

Suggested-by: Joseph Steel <[email protected]>
Signed-off-by: Ovidiu Panait <[email protected]>
---
v4 changes:
- New patch.

 .../net/ethernet/stmicro/stmmac/stmmac_vlan.c | 20 +++++++++++--------
 1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_vlan.c 
b/drivers/net/ethernet/stmicro/stmmac/stmmac_vlan.c
index 983a90cb9767..200b34588c7f 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_vlan.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_vlan.c
@@ -174,19 +174,16 @@ static void vlan_update_hash(struct mac_device_info *hw, 
u32 hash,
        if (hash) {
                value |= VLAN_VTHM | VLAN_ETV;
                if (is_double) {
-                       value |= VLAN_EDVLP;
                        value |= VLAN_ESVL;
                        value |= VLAN_DOVLTC;
                } else {
-                       value &= ~VLAN_EDVLP;
                        value &= ~VLAN_ESVL;
                        value &= ~VLAN_DOVLTC;
                }
 
                writel(value, ioaddr + VLAN_TAG);
        } else {
-               value &= ~(VLAN_VTHM | VLAN_ETV);
-               value &= ~(VLAN_EDVLP | VLAN_ESVL);
+               value &= ~(VLAN_VTHM | VLAN_ETV | VLAN_ESVL);
                value &= ~VLAN_DOVLTC;
                value &= ~VLAN_VID;
 
@@ -222,6 +219,7 @@ static void vlan_set_hw_mode(struct mac_device_info *hw)
        void __iomem *ioaddr = hw->pcsr;
        u32 value = readl(ioaddr + VLAN_TAG);
 
+       value |= VLAN_EDVLP;
        value &= ~VLAN_TAG_CTRL_EVLS_MASK;
 
        if (hw->hw_vlan_en)
@@ -254,11 +252,9 @@ static void dwxgmac2_update_vlan_hash(struct 
mac_device_info *hw, u32 hash,
 
                value |= VLAN_VTHM | VLAN_ETV;
                if (is_double) {
-                       value |= VLAN_EDVLP;
                        value |= VLAN_ESVL;
                        value |= VLAN_DOVLTC;
                } else {
-                       value &= ~VLAN_EDVLP;
                        value &= ~VLAN_ESVL;
                        value &= ~VLAN_DOVLTC;
                }
@@ -274,8 +270,7 @@ static void dwxgmac2_update_vlan_hash(struct 
mac_device_info *hw, u32 hash,
 
                value = readl(ioaddr + VLAN_TAG);
 
-               value &= ~(VLAN_VTHM | VLAN_ETV);
-               value &= ~(VLAN_EDVLP | VLAN_ESVL);
+               value &= ~(VLAN_VTHM | VLAN_ETV | VLAN_ESVL);
                value &= ~VLAN_DOVLTC;
                value &= ~VLAN_VID;
 
@@ -283,6 +278,14 @@ static void dwxgmac2_update_vlan_hash(struct 
mac_device_info *hw, u32 hash,
        }
 }
 
+static void dwxlgmac2_set_hw_vlan_mode(struct mac_device_info *hw)
+{
+       void __iomem *ioaddr = hw->pcsr;
+       u32 value = readl(ioaddr + VLAN_TAG);
+
+       writel(value | VLAN_EDVLP, ioaddr + VLAN_TAG);
+}
+
 const struct stmmac_vlan_ops dwmac_vlan_ops = {
        .update_vlan_hash = vlan_update_hash,
        .enable_vlan = vlan_enable,
@@ -296,6 +299,7 @@ const struct stmmac_vlan_ops dwmac_vlan_ops = {
 const struct stmmac_vlan_ops dwxlgmac2_vlan_ops = {
        .update_vlan_hash = dwxgmac2_update_vlan_hash,
        .enable_vlan = vlan_enable,
+       .set_hw_vlan_mode = dwxlgmac2_set_hw_vlan_mode,
 };
 
 const struct stmmac_vlan_ops dwxgmac210_vlan_ops = {
-- 
2.34.1


Reply via email to