Adds the support for VLAN HASH Filtering in GMAC4/5 cores.

Signed-off-by: Jose Abreu <joab...@synopsys.com>

---
Cc: Giuseppe Cavallaro <peppe.cavall...@st.com>
Cc: Alexandre Torgue <alexandre.tor...@st.com>
Cc: Jose Abreu <joab...@synopsys.com>
Cc: "David S. Miller" <da...@davemloft.net>
Cc: Maxime Coquelin <mcoquelin.st...@gmail.com>
Cc: net...@vger.kernel.org
Cc: linux-st...@st-md-mailman.stormreply.com
Cc: linux-arm-ker...@lists.infradead.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/net/ethernet/stmicro/stmmac/dwmac4.h      | 11 ++++++++
 drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c | 31 +++++++++++++++++++++++
 drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c  |  2 +-
 3 files changed, 43 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4.h 
b/drivers/net/ethernet/stmicro/stmmac/dwmac4.h
index 03301ffc0391..4dfa69850040 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4.h
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4.h
@@ -16,6 +16,8 @@
 #define GMAC_CONFIG                    0x00000000
 #define GMAC_PACKET_FILTER             0x00000008
 #define GMAC_HASH_TAB(x)               (0x10 + (x) * 4)
+#define GMAC_VLAN_TAG                  0x00000050
+#define GMAC_VLAN_HASH_TABLE           0x00000058
 #define GMAC_RX_FLOW_CTRL              0x00000090
 #define GMAC_QX_TX_FLOW_CTRL(x)                (0x70 + x * 4)
 #define GMAC_TXQ_PRTY_MAP0             0x98
@@ -62,9 +64,18 @@
 #define GMAC_PACKET_FILTER_PM          BIT(4)
 #define GMAC_PACKET_FILTER_PCF         BIT(7)
 #define GMAC_PACKET_FILTER_HPF         BIT(10)
+#define GMAC_PACKET_FILTER_VTFE                BIT(16)
 
 #define GMAC_MAX_PERFECT_ADDRESSES     128
 
+/* MAC VLAN */
+#define GMAC_VLAN_EDVLP                        BIT(26)
+#define GMAC_VLAN_VTHM                 BIT(25)
+#define GMAC_VLAN_DOVLTC               BIT(20)
+#define GMAC_VLAN_ESVL                 BIT(18)
+#define GMAC_VLAN_ETV                  BIT(16)
+#define GMAC_VLAN_VID                  GENMASK(15, 0)
+
 /* MAC RX Queue Enable */
 #define GMAC_RX_QUEUE_CLEAR(queue)     ~(GENMASK(1, 0) << ((queue) * 2))
 #define GMAC_RX_AV_QUEUE_ENABLE(queue) BIT((queue) * 2)
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
index 596311a80d1c..5b43a8df1536 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
@@ -731,6 +731,34 @@ static void dwmac4_set_mac_loopback(void __iomem *ioaddr, 
bool enable)
        writel(value, ioaddr + GMAC_CONFIG);
 }
 
+static void dwmac4_update_vlan_hash(struct mac_device_info *hw, u32 hash,
+                                   bool is_double)
+{
+       void __iomem *ioaddr = hw->pcsr;
+
+       writel(hash, ioaddr + GMAC_VLAN_HASH_TABLE);
+
+       if (hash) {
+               u32 value = GMAC_VLAN_VTHM | GMAC_VLAN_ETV;
+               if (is_double) {
+                       value |= GMAC_VLAN_EDVLP;
+                       value |= GMAC_VLAN_ESVL;
+                       value |= GMAC_VLAN_DOVLTC;
+               }
+
+               writel(value, ioaddr + GMAC_VLAN_TAG);
+       } else {
+               u32 value = readl(ioaddr + GMAC_VLAN_TAG);
+
+               value &= ~(GMAC_VLAN_VTHM | GMAC_VLAN_ETV);
+               value &= ~(GMAC_VLAN_EDVLP | GMAC_VLAN_ESVL);
+               value &= ~GMAC_VLAN_DOVLTC;
+               value &= ~GMAC_VLAN_VID;
+
+               writel(value, ioaddr + GMAC_VLAN_TAG);
+       }
+}
+
 const struct stmmac_ops dwmac4_ops = {
        .core_init = dwmac4_core_init,
        .set_mac = stmmac_set_mac,
@@ -761,6 +789,7 @@ const struct stmmac_ops dwmac4_ops = {
        .debug = dwmac4_debug,
        .set_filter = dwmac4_set_filter,
        .set_mac_loopback = dwmac4_set_mac_loopback,
+       .update_vlan_hash = dwmac4_update_vlan_hash,
 };
 
 const struct stmmac_ops dwmac410_ops = {
@@ -793,6 +822,7 @@ const struct stmmac_ops dwmac410_ops = {
        .debug = dwmac4_debug,
        .set_filter = dwmac4_set_filter,
        .set_mac_loopback = dwmac4_set_mac_loopback,
+       .update_vlan_hash = dwmac4_update_vlan_hash,
 };
 
 const struct stmmac_ops dwmac510_ops = {
@@ -830,6 +860,7 @@ const struct stmmac_ops dwmac510_ops = {
        .rxp_config = dwmac5_rxp_config,
        .flex_pps_config = dwmac5_flex_pps_config,
        .set_mac_loopback = dwmac4_set_mac_loopback,
+       .update_vlan_hash = dwmac4_update_vlan_hash,
 };
 
 int dwmac4_setup(struct stmmac_priv *priv)
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c
index 3ed5508586ef..2456f421aac9 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c
@@ -333,7 +333,7 @@ static void dwmac4_get_hw_feature(void __iomem *ioaddr,
        dma_cap->mbps_10_100 = (hw_cap & GMAC_HW_FEAT_MIISEL);
        dma_cap->mbps_1000 = (hw_cap & GMAC_HW_FEAT_GMIISEL) >> 1;
        dma_cap->half_duplex = (hw_cap & GMAC_HW_FEAT_HDSEL) >> 2;
-       dma_cap->hash_filter = (hw_cap & GMAC_HW_FEAT_VLHASH) >> 4;
+       dma_cap->vlhash = (hw_cap & GMAC_HW_FEAT_VLHASH) >> 4;
        dma_cap->multi_addr = (hw_cap & GMAC_HW_FEAT_ADDMAC) >> 18;
        dma_cap->pcs = (hw_cap & GMAC_HW_FEAT_PCSSEL) >> 3;
        dma_cap->sma_mdio = (hw_cap & GMAC_HW_FEAT_SMASEL) >> 5;
-- 
2.7.4

Reply via email to