]> git.proxmox.com Git - mirror_ubuntu-kernels.git/commitdiff
net: stmmac: Add basic EST support for XGMAC
authorJose Abreu <Jose.Abreu@synopsys.com>
Wed, 18 Dec 2019 10:33:06 +0000 (11:33 +0100)
committerDavid S. Miller <davem@davemloft.net>
Wed, 18 Dec 2019 20:17:11 +0000 (12:17 -0800)
Adds the support for EST in XGMAC cores. This feature allows to offload
scheduling of queues opening time to the IP.

Signed-off-by: Jose Abreu <Jose.Abreu@synopsys.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c

index 158cf4ad1596f7e72374c8aac95cb2f5a93f1a46..e1e79c90c865a25c2b86e4865f868388046976c9 100644 (file)
 #define XGMAC_HWFEAT_TXQCNT            GENMASK(9, 6)
 #define XGMAC_HWFEAT_RXQCNT            GENMASK(3, 0)
 #define XGMAC_HW_FEATURE3              0x00000128
+#define XGMAC_HWFEAT_ESTWID            GENMASK(24, 23)
+#define XGMAC_HWFEAT_ESTDEP            GENMASK(22, 20)
+#define XGMAC_HWFEAT_ESTSEL            BIT(19)
 #define XGMAC_HWFEAT_ASP               GENMASK(15, 14)
 #define XGMAC_HWFEAT_DVLAN             BIT(13)
 #define XGMAC_HWFEAT_FRPES             GENMASK(12, 11)
 #define XGMAC_TC_PRTY_MAP1             0x00001044
 #define XGMAC_PSTC(x)                  GENMASK((x) * 8 + 7, (x) * 8)
 #define XGMAC_PSTC_SHIFT(x)            ((x) * 8)
+#define XGMAC_MTL_EST_CONTROL          0x00001050
+#define XGMAC_PTOV                     GENMASK(31, 23)
+#define XGMAC_PTOV_SHIFT               23
+#define XGMAC_SSWL                     BIT(1)
+#define XGMAC_EEST                     BIT(0)
+#define XGMAC_MTL_EST_GCL_CONTROL      0x00001080
+#define XGMAC_BTR_LOW                  0x0
+#define XGMAC_BTR_HIGH                 0x1
+#define XGMAC_CTR_LOW                  0x2
+#define XGMAC_CTR_HIGH                 0x3
+#define XGMAC_TER                      0x4
+#define XGMAC_LLR                      0x5
+#define XGMAC_ADDR_SHIFT               8
+#define XGMAC_GCRR                     BIT(2)
+#define XGMAC_SRWO                     BIT(0)
+#define XGMAC_MTL_EST_GCL_DATA         0x00001084
 #define XGMAC_MTL_RXP_CONTROL_STATUS   0x000010a0
 #define XGMAC_RXPI                     BIT(31)
 #define XGMAC_NPE                      GENMASK(23, 16)
index 082f5ee9e52566ae06fca10463fe69cd7af37257..2f6e960947d9dc3e3af3cb12fbc9fa0b918c3daa 100644 (file)
@@ -1359,6 +1359,57 @@ static void dwxgmac2_set_arp_offload(struct mac_device_info *hw, bool en,
        writel(value, ioaddr + XGMAC_RX_CONFIG);
 }
 
+static int dwxgmac3_est_write(void __iomem *ioaddr, u32 reg, u32 val, bool gcl)
+{
+       u32 ctrl;
+
+       writel(val, ioaddr + XGMAC_MTL_EST_GCL_DATA);
+
+       ctrl = (reg << XGMAC_ADDR_SHIFT);
+       ctrl |= gcl ? 0 : XGMAC_GCRR;
+
+       writel(ctrl, ioaddr + XGMAC_MTL_EST_GCL_CONTROL);
+
+       ctrl |= XGMAC_SRWO;
+       writel(ctrl, ioaddr + XGMAC_MTL_EST_GCL_CONTROL);
+
+       return readl_poll_timeout_atomic(ioaddr + XGMAC_MTL_EST_GCL_CONTROL,
+                                        ctrl, !(ctrl & XGMAC_SRWO), 100, 5000);
+}
+
+static int dwxgmac3_est_configure(void __iomem *ioaddr, struct stmmac_est *cfg,
+                                 unsigned int ptp_rate)
+{
+       int i, ret = 0x0;
+       u32 ctrl;
+
+       ret |= dwxgmac3_est_write(ioaddr, XGMAC_BTR_LOW, cfg->btr[0], false);
+       ret |= dwxgmac3_est_write(ioaddr, XGMAC_BTR_HIGH, cfg->btr[1], false);
+       ret |= dwxgmac3_est_write(ioaddr, XGMAC_TER, cfg->ter, false);
+       ret |= dwxgmac3_est_write(ioaddr, XGMAC_LLR, cfg->gcl_size, false);
+       ret |= dwxgmac3_est_write(ioaddr, XGMAC_CTR_LOW, cfg->ctr[0], false);
+       ret |= dwxgmac3_est_write(ioaddr, XGMAC_CTR_HIGH, cfg->ctr[1], false);
+       if (ret)
+               return ret;
+
+       for (i = 0; i < cfg->gcl_size; i++) {
+               ret = dwxgmac3_est_write(ioaddr, i, cfg->gcl[i], true);
+               if (ret)
+                       return ret;
+       }
+
+       ctrl = readl(ioaddr + XGMAC_MTL_EST_CONTROL);
+       ctrl &= ~XGMAC_PTOV;
+       ctrl |= ((1000000000 / ptp_rate) * 9) << XGMAC_PTOV_SHIFT;
+       if (cfg->enable)
+               ctrl |= XGMAC_EEST | XGMAC_SSWL;
+       else
+               ctrl &= ~XGMAC_EEST;
+
+       writel(ctrl, ioaddr + XGMAC_MTL_EST_CONTROL);
+       return 0;
+}
+
 const struct stmmac_ops dwxgmac210_ops = {
        .core_init = dwxgmac2_core_init,
        .set_mac = dwxgmac2_set_mac,
@@ -1402,6 +1453,7 @@ const struct stmmac_ops dwxgmac210_ops = {
        .config_l3_filter = dwxgmac2_config_l3_filter,
        .config_l4_filter = dwxgmac2_config_l4_filter,
        .set_arp_offload = dwxgmac2_set_arp_offload,
+       .est_configure = dwxgmac3_est_configure,
 };
 
 int dwxgmac2_setup(struct stmmac_priv *priv)
index ae066f4e99a81b9654e5d91a74f5dd46f2916914..6ff2795a51175b18f1014d005e19e7c35d293bfc 100644 (file)
@@ -429,6 +429,9 @@ static void dwxgmac2_get_hw_feature(void __iomem *ioaddr,
 
        /* MAC HW feature 3 */
        hw_cap = readl(ioaddr + XGMAC_HW_FEATURE3);
+       dma_cap->estwid = (hw_cap & XGMAC_HWFEAT_ESTWID) >> 23;
+       dma_cap->estdep = (hw_cap & XGMAC_HWFEAT_ESTDEP) >> 20;
+       dma_cap->estsel = (hw_cap & XGMAC_HWFEAT_ESTSEL) >> 19;
        dma_cap->asp = (hw_cap & XGMAC_HWFEAT_ASP) >> 14;
        dma_cap->dvlan = (hw_cap & XGMAC_HWFEAT_DVLAN) >> 13;
        dma_cap->frpes = (hw_cap & XGMAC_HWFEAT_FRPES) >> 11;