Add the support for Source Address Insertion and Replacement in GMAC4
and GMAC5 cores. Two methods are supported: Descriptor based and
register based.

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       |  3 +++
 drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c  | 13 +++++++++++++
 drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c |  8 ++++++++
 drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.h |  1 +
 drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c   |  1 +
 5 files changed, 26 insertions(+)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4.h 
b/drivers/net/ethernet/stmicro/stmmac/dwmac4.h
index 4dfa69850040..fad121cbfe0e 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4.h
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4.h
@@ -160,6 +160,8 @@ enum power_event {
 #define GMAC_DEBUG_RPESTS              BIT(0)
 
 /* MAC config */
+#define GMAC_CONFIG_SARC               GENMASK(30, 28)
+#define GMAC_CONFIG_SARC_SHIFT         28
 #define GMAC_CONFIG_IPC                        BIT(27)
 #define GMAC_CONFIG_2K                 BIT(22)
 #define GMAC_CONFIG_ACS                        BIT(20)
@@ -175,6 +177,7 @@ enum power_event {
 #define GMAC_CONFIG_RE                 BIT(0)
 
 /* MAC HW features0 bitmap */
+#define GMAC_HW_FEAT_SAVLANINS         BIT(27)
 #define GMAC_HW_FEAT_ADDMAC            BIT(18)
 #define GMAC_HW_FEAT_RXCOESEL          BIT(16)
 #define GMAC_HW_FEAT_TXCOSEL           BIT(14)
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
index 5b43a8df1536..73dbfd810fca 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
@@ -759,6 +759,16 @@ static void dwmac4_update_vlan_hash(struct mac_device_info 
*hw, u32 hash,
        }
 }
 
+static void dwmac4_sarc_configure(void __iomem *ioaddr, int val)
+{
+       u32 value = readl(ioaddr + GMAC_CONFIG);
+
+       value &= ~GMAC_CONFIG_SARC;
+       value |= val << GMAC_CONFIG_SARC_SHIFT;
+
+       writel(value, ioaddr + GMAC_CONFIG);
+}
+
 const struct stmmac_ops dwmac4_ops = {
        .core_init = dwmac4_core_init,
        .set_mac = stmmac_set_mac,
@@ -790,6 +800,7 @@ const struct stmmac_ops dwmac4_ops = {
        .set_filter = dwmac4_set_filter,
        .set_mac_loopback = dwmac4_set_mac_loopback,
        .update_vlan_hash = dwmac4_update_vlan_hash,
+       .sarc_configure = dwmac4_sarc_configure,
 };
 
 const struct stmmac_ops dwmac410_ops = {
@@ -823,6 +834,7 @@ const struct stmmac_ops dwmac410_ops = {
        .set_filter = dwmac4_set_filter,
        .set_mac_loopback = dwmac4_set_mac_loopback,
        .update_vlan_hash = dwmac4_update_vlan_hash,
+       .sarc_configure = dwmac4_sarc_configure,
 };
 
 const struct stmmac_ops dwmac510_ops = {
@@ -861,6 +873,7 @@ const struct stmmac_ops dwmac510_ops = {
        .flex_pps_config = dwmac5_flex_pps_config,
        .set_mac_loopback = dwmac4_set_mac_loopback,
        .update_vlan_hash = dwmac4_update_vlan_hash,
+       .sarc_configure = dwmac4_sarc_configure,
 };
 
 int dwmac4_setup(struct stmmac_priv *priv)
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c
index dbde23e7e169..8edc9f8787cc 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c
@@ -443,6 +443,13 @@ static void dwmac4_clear(struct dma_desc *p)
        p->des3 = 0;
 }
 
+static void dwmac4_set_sarc(struct dma_desc *p, u32 sarc_type)
+{
+       sarc_type <<= TDES3_SA_INSERT_CTRL_SHIFT;
+
+       p->des3 |= cpu_to_le32(sarc_type & TDES3_SA_INSERT_CTRL_MASK);
+}
+
 static int set_16kib_bfsize(int mtu)
 {
        int ret = 0;
@@ -476,6 +483,7 @@ const struct stmmac_desc_ops dwmac4_desc_ops = {
        .get_addr = dwmac4_get_addr,
        .set_addr = dwmac4_set_addr,
        .clear = dwmac4_clear,
+       .set_sarc = dwmac4_set_sarc,
 };
 
 const struct stmmac_mode_ops dwmac4_ring_mode_ops = {
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.h 
b/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.h
index f58191174287..6089d76a00d3 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.h
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.h
@@ -32,6 +32,7 @@
 #define TDES3_HDR_LEN_SHIFT            19
 #define TDES3_SLOT_NUMBER_MASK         GENMASK(22, 19)
 #define TDES3_SA_INSERT_CTRL_MASK      GENMASK(25, 23)
+#define TDES3_SA_INSERT_CTRL_SHIFT     23
 #define TDES3_CRC_PAD_CTRL_MASK                GENMASK(27, 26)
 
 /* TDES3 (write back format) */
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c
index 2456f421aac9..82d9761b2df2 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c
@@ -348,6 +348,7 @@ static void dwmac4_get_hw_feature(void __iomem *ioaddr,
        /* TX and RX csum */
        dma_cap->tx_coe = (hw_cap & GMAC_HW_FEAT_TXCOSEL) >> 14;
        dma_cap->rx_coe =  (hw_cap & GMAC_HW_FEAT_RXCOESEL) >> 16;
+       dma_cap->vlins = (hw_cap & GMAC_HW_FEAT_SAVLANINS) >> 27;
 
        /* MAC HW feature1 */
        hw_cap = readl(ioaddr + GMAC_HW_FEATURE1);
-- 
2.7.4

Reply via email to