summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c20
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_vlan.h1
2 files changed, 21 insertions, 0 deletions
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
index a50f79a47266..a05f448bfd7a 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
@@ -6,6 +6,7 @@
#include <linux/iopoll.h>
#include "stmmac.h"
+#include "stmmac_vlan.h"
#include "dwxgmac2.h"
static int dwxgmac2_dma_reset(void __iomem *ioaddr)
@@ -388,6 +389,20 @@ static int dwxgmac2_dma_interrupt(struct stmmac_priv *priv,
return ret;
}
+static bool dwxgmac2_det_hw_dvlan(void __iomem *ioaddr)
+{
+ u32 tmp;
+
+ tmp = readl(ioaddr + VLAN_TAG);
+ writel(tmp ^ VLAN_EIVLRXS, ioaddr + VLAN_TAG);
+ if (tmp != readl(ioaddr + VLAN_TAG)) {
+ writel(tmp, ioaddr + VLAN_TAG);
+ return true;
+ }
+
+ return false;
+}
+
static int dwxgmac2_get_hw_feature(void __iomem *ioaddr,
struct dma_features *dma_cap)
{
@@ -492,7 +507,12 @@ static int dwxgmac2_get_hw_feature(void __iomem *ioaddr,
dma_cap->estsel = (hw_cap & XGMAC_HWFEAT_ESTSEL) >> 19;
dma_cap->ttsfd = (hw_cap & XGMAC_HWFEAT_TTSFD) >> 16;
dma_cap->asp = (hw_cap & XGMAC_HWFEAT_ASP) >> 14;
+
+ /* Double VLAN Tagging (flag is unavailable prior DW XGMAC v3.00a) */
dma_cap->dvlan = (hw_cap & XGMAC_HWFEAT_DVLAN) >> 13;
+ if (!dma_cap->dvlan)
+ dma_cap->dvlan = dwxgmac2_det_hw_dvlan(ioaddr);
+
dma_cap->frpes = (hw_cap & XGMAC_HWFEAT_FRPES) >> 11;
dma_cap->frpbs = (hw_cap & XGMAC_HWFEAT_FRPPB) >> 9;
dma_cap->pou_ost_en = (hw_cap & XGMAC_HWFEAT_POUOST) >> 8;
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_vlan.h b/drivers/net/ethernet/stmicro/stmmac/stmmac_vlan.h
index 5143c0fbda26..a138f4fdc4d8 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_vlan.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_vlan.h
@@ -15,6 +15,7 @@
#define VLAN_INCL 0x00000060
/* MAC VLAN */
+#define VLAN_EIVLRXS BIT(31)
#define VLAN_EDVLP BIT(26)
#define VLAN_VTHM BIT(25)
#define VLAN_DOVLTC BIT(20)