net: stmmac: Add support for VLAN Insertion Offload in GMAC4+
authorJose Abreu <Jose.Abreu@synopsys.com>
Tue, 10 Sep 2019 14:41:26 +0000 (16:41 +0200)
committerDavid S. Miller <davem@davemloft.net>
Wed, 11 Sep 2019 08:21:34 +0000 (09:21 +0100)
Adds support for TX VLAN Offload using descriptors based features
available in GMAC4/5.

Signed-off-by: Jose Abreu <joabreu@synopsys.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/stmicro/stmmac/dwmac4.h
drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c
drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.h
drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c

index fad121cbfe0e1a13f41a395b6b2242382b5fa439..e88dac1dd765e90aaf4b82f6e3476697f1c838dd 100644 (file)
@@ -19,6 +19,7 @@
 #define GMAC_VLAN_TAG                  0x00000050
 #define GMAC_VLAN_HASH_TABLE           0x00000058
 #define GMAC_RX_FLOW_CTRL              0x00000090
+#define GMAC_VLAN_INCL                 0x00000060
 #define GMAC_QX_TX_FLOW_CTRL(x)                (0x70 + x * 4)
 #define GMAC_TXQ_PRTY_MAP0             0x98
 #define GMAC_TXQ_PRTY_MAP1             0x9C
 #define GMAC_VLAN_ESVL                 BIT(18)
 #define GMAC_VLAN_ETV                  BIT(16)
 #define GMAC_VLAN_VID                  GENMASK(15, 0)
+#define GMAC_VLAN_VLTI                 BIT(20)
+#define GMAC_VLAN_CSVL                 BIT(19)
+#define GMAC_VLAN_VLC                  GENMASK(17, 16)
+#define GMAC_VLAN_VLC_SHIFT            16
 
 /* MAC RX Queue Enable */
 #define GMAC_RX_QUEUE_CLEAR(queue)     ~(GENMASK(1, 0) << ((queue) * 2))
@@ -212,6 +217,7 @@ enum power_event {
 #define GMAC_HW_FEAT_FRPES             GENMASK(14, 13)
 #define GMAC_HW_FEAT_FRPBS             GENMASK(12, 11)
 #define GMAC_HW_FEAT_FRPSEL            BIT(10)
+#define GMAC_HW_FEAT_DVLAN             BIT(5)
 
 /* MAC HW ADDR regs */
 #define GMAC_HI_DCS                    GENMASK(18, 16)
index 73dbfd810fca7800867a6d64a818f76563164d40..a99effe6132558c325a669e46af032c70aaf5a01 100644 (file)
@@ -769,6 +769,19 @@ static void dwmac4_sarc_configure(void __iomem *ioaddr, int val)
        writel(value, ioaddr + GMAC_CONFIG);
 }
 
+static void dwmac4_enable_vlan(struct mac_device_info *hw, u32 type)
+{
+       void __iomem *ioaddr = hw->pcsr;
+       u32 value;
+
+       value = readl(ioaddr + GMAC_VLAN_INCL);
+       value |= GMAC_VLAN_VLTI;
+       value |= GMAC_VLAN_CSVL; /* Only use SVLAN */
+       value &= ~GMAC_VLAN_VLC;
+       value |= (type << GMAC_VLAN_VLC_SHIFT) & GMAC_VLAN_VLC;
+       writel(value, ioaddr + GMAC_VLAN_INCL);
+}
+
 const struct stmmac_ops dwmac4_ops = {
        .core_init = dwmac4_core_init,
        .set_mac = stmmac_set_mac,
@@ -801,6 +814,7 @@ const struct stmmac_ops dwmac4_ops = {
        .set_mac_loopback = dwmac4_set_mac_loopback,
        .update_vlan_hash = dwmac4_update_vlan_hash,
        .sarc_configure = dwmac4_sarc_configure,
+       .enable_vlan = dwmac4_enable_vlan,
 };
 
 const struct stmmac_ops dwmac410_ops = {
@@ -835,6 +849,7 @@ const struct stmmac_ops dwmac410_ops = {
        .set_mac_loopback = dwmac4_set_mac_loopback,
        .update_vlan_hash = dwmac4_update_vlan_hash,
        .sarc_configure = dwmac4_sarc_configure,
+       .enable_vlan = dwmac4_enable_vlan,
 };
 
 const struct stmmac_ops dwmac510_ops = {
@@ -874,6 +889,7 @@ const struct stmmac_ops dwmac510_ops = {
        .set_mac_loopback = dwmac4_set_mac_loopback,
        .update_vlan_hash = dwmac4_update_vlan_hash,
        .sarc_configure = dwmac4_sarc_configure,
+       .enable_vlan = dwmac4_enable_vlan,
 };
 
 int dwmac4_setup(struct stmmac_priv *priv)
index 8edc9f8787ccd0b8a8a8b333be3f748ffe42dff0..15eb1abba91da920926309ecc133a8a24bbdcc1b 100644 (file)
@@ -459,6 +459,39 @@ static int set_16kib_bfsize(int mtu)
        return ret;
 }
 
+static void dwmac4_set_vlan_tag(struct dma_desc *p, u16 tag, u16 inner_tag,
+                               u32 inner_type)
+{
+       p->des0 = 0;
+       p->des1 = 0;
+       p->des2 = 0;
+       p->des3 = 0;
+
+       /* Inner VLAN */
+       if (inner_type) {
+               u32 des = inner_tag << TDES2_IVT_SHIFT;
+
+               des &= TDES2_IVT_MASK;
+               p->des2 = cpu_to_le32(des);
+
+               des = inner_type << TDES3_IVTIR_SHIFT;
+               des &= TDES3_IVTIR_MASK;
+               p->des3 = cpu_to_le32(des | TDES3_IVLTV);
+       }
+
+       /* Outer VLAN */
+       p->des3 |= cpu_to_le32(tag & TDES3_VLAN_TAG);
+       p->des3 |= cpu_to_le32(TDES3_VLTV);
+
+       p->des3 |= cpu_to_le32(TDES3_CONTEXT_TYPE);
+}
+
+static void dwmac4_set_vlan(struct dma_desc *p, u32 type)
+{
+       type <<= TDES2_VLAN_TAG_SHIFT;
+       p->des2 |= cpu_to_le32(type & TDES2_VLAN_TAG_MASK);
+}
+
 const struct stmmac_desc_ops dwmac4_desc_ops = {
        .tx_status = dwmac4_wrback_get_tx_status,
        .rx_status = dwmac4_wrback_get_rx_status,
@@ -484,6 +517,8 @@ const struct stmmac_desc_ops dwmac4_desc_ops = {
        .set_addr = dwmac4_set_addr,
        .clear = dwmac4_clear,
        .set_sarc = dwmac4_set_sarc,
+       .set_vlan_tag = dwmac4_set_vlan_tag,
+       .set_vlan = dwmac4_set_vlan,
 };
 
 const struct stmmac_mode_ops dwmac4_ring_mode_ops = {
index 6089d76a00d3fa7113f3e3da0790521c5eaab0ed..0d7b3bbcd5a778509dc4cc16fb976a5a859a7b64 100644 (file)
 /* TDES2 (read format) */
 #define TDES2_BUFFER1_SIZE_MASK                GENMASK(13, 0)
 #define TDES2_VLAN_TAG_MASK            GENMASK(15, 14)
+#define TDES2_VLAN_TAG_SHIFT           14
 #define TDES2_BUFFER2_SIZE_MASK                GENMASK(29, 16)
 #define TDES2_BUFFER2_SIZE_MASK_SHIFT  16
+#define TDES3_IVTIR_MASK               GENMASK(19, 18)
+#define TDES3_IVTIR_SHIFT              18
+#define TDES3_IVLTV                    BIT(17)
 #define TDES2_TIMESTAMP_ENABLE         BIT(30)
+#define TDES2_IVT_MASK                 GENMASK(31, 16)
+#define TDES2_IVT_SHIFT                        16
 #define TDES2_INTERRUPT_ON_COMPLETION  BIT(31)
 
 /* TDES3 (read format) */
 #define TDES3_PACKET_SIZE_MASK         GENMASK(14, 0)
+#define TDES3_VLAN_TAG                 GENMASK(15, 0)
+#define TDES3_VLTV                     BIT(16)
 #define TDES3_CHECKSUM_INSERTION_MASK  GENMASK(17, 16)
 #define TDES3_CHECKSUM_INSERTION_SHIFT 16
 #define TDES3_TCP_PKT_PAYLOAD_MASK     GENMASK(17, 0)
index 82d9761b2df28f8972250f5982155eb1888f0a2d..f3ca0236450d71f3ddb8c51c5695a909e668faa6 100644 (file)
@@ -386,6 +386,7 @@ static void dwmac4_get_hw_feature(void __iomem *ioaddr,
        dma_cap->frpes = (hw_cap & GMAC_HW_FEAT_FRPES) >> 13;
        dma_cap->frpbs = (hw_cap & GMAC_HW_FEAT_FRPBS) >> 11;
        dma_cap->frpsel = (hw_cap & GMAC_HW_FEAT_FRPSEL) >> 10;
+       dma_cap->dvlan = (hw_cap & GMAC_HW_FEAT_DVLAN) >> 5;
 }
 
 /* Enable/disable TSO feature and set MSS */