net: stmmac: configuration of CBS in case of a TX AVB queue
authorJoao Pinto <Joao.Pinto@synopsys.com>
Fri, 10 Mar 2017 18:24:59 +0000 (18:24 +0000)
committerDavid S. Miller <davem@davemloft.net>
Mon, 13 Mar 2017 06:41:04 +0000 (23:41 -0700)
This patch adds the configuration of the AVB Credit-Based Shaper.

Signed-off-by: Joao Pinto <jpinto@synopsys.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Documentation/devicetree/bindings/net/stmmac.txt
drivers/net/ethernet/stmicro/stmmac/common.h
drivers/net/ethernet/stmicro/stmmac/dwmac4.h
drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
include/linux/stmmac.h

index 04a258e2d4e07fd0f7b92066e30ac9a5d1efc2d2..a7b0e41cb2647060b10ee68ab77cf532d9bce3c1 100644 (file)
@@ -92,8 +92,15 @@ Optional properties:
                - snps,tx-sched-dwrr: Deficit Weighted Round Robin
                - snps,tx-sched-sp: Strict priority
        - For each TX queue
-               - snps,weight: TX queue weight (if using a weighted algorithm)
-
+               - snps,weight: TX queue weight (if using a DCB weight algorithm)
+               - Choose one of these modes:
+                       - snps,dcb-algorithm: TX queue will be working in DCB
+                       - snps,avb-algorithm: TX queue will be working in AVB
+               - Configure Credit Base Shaper (if AVB Mode selected):
+                       - snps,send_slope: enable Low Power Interface
+                       - snps,idle_slope: unlock on WoL
+                       - snps,high_credit: max write outstanding req. limit
+                       - snps,low_credit: max read outstanding req. limit
 Examples:
 
        stmmac_axi_setup: stmmac-axi-config {
@@ -112,10 +119,19 @@ Examples:
        };
 
        mtl_tx_setup: tx-queues-config {
-               snps,tx-queues-to-use = <1>;
+               snps,tx-queues-to-use = <2>;
                snps,tx-sched-wrr;
                queue0 {
                        snps,weight = <0x10>;
+                       snps,dcb-algorithm;
+               };
+
+               queue1 {
+                       snps,avb-algorithm;
+                       snps,send_slope = <0x1000>;
+                       snps,idle_slope = <0x1000>;
+                       snps,high_credit = <0x3E800>;
+                       snps,low_credit = <0xFFC18000>;
                };
        };
 
index e7fb98569d2d9aefde9d8e146518234537f5dee7..9f0d26da6813bebcef47044bffa5c7072f27e8f2 100644 (file)
@@ -467,6 +467,10 @@ struct stmmac_ops {
                                        u32 weight, u32 queue);
        /* RX MTL queue to RX dma mapping */
        void (*map_mtl_to_dma)(struct mac_device_info *hw, u32 queue, u32 chan);
+       /* Configure AV Algorithm */
+       void (*config_cbs)(struct mac_device_info *hw, u32 send_slope,
+                          u32 idle_slope, u32 high_credit, u32 low_credit,
+                          u32 queue);
        /* Dump MAC registers */
        void (*dump_regs)(struct mac_device_info *hw, u32 *reg_space);
        /* Handle extra events on specific interrupts hw dependent */
index 1ddf75c0eab5fe33517b39e4df9f1b806be53de2..54bcdb4d10dba88181309266fb2013308eae11d3 100644 (file)
@@ -233,6 +233,15 @@ enum power_event {
 #define MTL_OP_MODE_RTC_96             (2 << MTL_OP_MODE_RTC_SHIFT)
 #define MTL_OP_MODE_RTC_128            (3 << MTL_OP_MODE_RTC_SHIFT)
 
+/* MTL ETS Control register */
+#define MTL_ETS_CTRL_BASE_ADDR         0x00000d10
+#define MTL_ETS_CTRL_BASE_OFFSET       0x40
+#define MTL_ETSX_CTRL_BASE_ADDR(x)     (MTL_ETS_CTRL_BASE_ADDR + \
+                                       ((x) * MTL_ETS_CTRL_BASE_OFFSET))
+
+#define MTL_ETS_CTRL_CC                        BIT(3)
+#define MTL_ETS_CTRL_AVALG             BIT(2)
+
 /* MTL Queue Quantum Weight */
 #define MTL_TXQ_WEIGHT_BASE_ADDR       0x00000d18
 #define MTL_TXQ_WEIGHT_BASE_OFFSET     0x40
@@ -240,6 +249,30 @@ enum power_event {
                                        ((x) * MTL_TXQ_WEIGHT_BASE_OFFSET))
 #define MTL_TXQ_WEIGHT_ISCQW_MASK      GENMASK(20, 0)
 
+/* MTL sendSlopeCredit register */
+#define MTL_SEND_SLP_CRED_BASE_ADDR    0x00000d1c
+#define MTL_SEND_SLP_CRED_OFFSET       0x40
+#define MTL_SEND_SLP_CREDX_BASE_ADDR(x)        (MTL_SEND_SLP_CRED_BASE_ADDR + \
+                                       ((x) * MTL_SEND_SLP_CRED_OFFSET))
+
+#define MTL_SEND_SLP_CRED_SSC_MASK     GENMASK(13, 0)
+
+/* MTL hiCredit register */
+#define MTL_HIGH_CRED_BASE_ADDR                0x00000d20
+#define MTL_HIGH_CRED_OFFSET           0x40
+#define MTL_HIGH_CREDX_BASE_ADDR(x)    (MTL_HIGH_CRED_BASE_ADDR + \
+                                       ((x) * MTL_HIGH_CRED_OFFSET))
+
+#define MTL_HIGH_CRED_HC_MASK          GENMASK(28, 0)
+
+/* MTL loCredit register */
+#define MTL_LOW_CRED_BASE_ADDR         0x00000d24
+#define MTL_LOW_CRED_OFFSET            0x40
+#define MTL_LOW_CREDX_BASE_ADDR(x)     (MTL_LOW_CRED_BASE_ADDR + \
+                                       ((x) * MTL_LOW_CRED_OFFSET))
+
+#define MTL_HIGH_CRED_LC_MASK          GENMASK(28, 0)
+
 /*  MTL debug */
 #define MTL_DEBUG_TXSTSFSTS            BIT(5)
 #define MTL_DEBUG_TXFSTS               BIT(4)
index 670cfee415fd3684d0f27a6a701ad1c0cc332886..10599dbc232fbda9684ed46a9fd24d2294a548f5 100644 (file)
@@ -66,9 +66,9 @@ static void dwmac4_rx_queue_enable(struct mac_device_info *hw,
        u32 value = readl(ioaddr + GMAC_RXQ_CTRL0);
 
        value &= GMAC_RX_QUEUE_CLEAR(queue);
-       if (mode == MTL_RX_AVB)
+       if (mode == MTL_QUEUE_AVB)
                value |= GMAC_RX_AV_QUEUE_ENABLE(queue);
-       else if (mode == MTL_RX_DCB)
+       else if (mode == MTL_QUEUE_DCB)
                value |= GMAC_RX_DCB_QUEUE_ENABLE(queue);
 
        writel(value, ioaddr + GMAC_RXQ_CTRL0);
@@ -155,6 +155,47 @@ static void dwmac4_map_mtl_dma(struct mac_device_info *hw, u32 queue, u32 chan)
                writel(value, ioaddr + MTL_RXQ_DMA_MAP1);
 }
 
+static void dwmac4_config_cbs(struct mac_device_info *hw,
+                             u32 send_slope, u32 idle_slope,
+                             u32 high_credit, u32 low_credit, u32 queue)
+{
+       void __iomem *ioaddr = hw->pcsr;
+       u32 value;
+
+       pr_debug("Queue %d configured as AVB. Parameters:\n", queue);
+       pr_debug("\tsend_slope: 0x%08x\n", send_slope);
+       pr_debug("\tidle_slope: 0x%08x\n", idle_slope);
+       pr_debug("\thigh_credit: 0x%08x\n", high_credit);
+       pr_debug("\tlow_credit: 0x%08x\n", low_credit);
+
+       /* enable AV algorithm */
+       value = readl(ioaddr + MTL_ETSX_CTRL_BASE_ADDR(queue));
+       value |= MTL_ETS_CTRL_AVALG;
+       value |= MTL_ETS_CTRL_CC;
+       writel(value, ioaddr + MTL_ETSX_CTRL_BASE_ADDR(queue));
+
+       /* configure send slope */
+       value = readl(ioaddr + MTL_SEND_SLP_CREDX_BASE_ADDR(queue));
+       value &= ~MTL_SEND_SLP_CRED_SSC_MASK;
+       value |= send_slope & MTL_SEND_SLP_CRED_SSC_MASK;
+       writel(value, ioaddr + MTL_SEND_SLP_CREDX_BASE_ADDR(queue));
+
+       /* configure idle slope (same register as tx weight) */
+       dwmac4_set_mtl_tx_queue_weight(hw, idle_slope, queue);
+
+       /* configure high credit */
+       value = readl(ioaddr + MTL_HIGH_CREDX_BASE_ADDR(queue));
+       value &= ~MTL_HIGH_CRED_HC_MASK;
+       value |= high_credit & MTL_HIGH_CRED_HC_MASK;
+       writel(value, ioaddr + MTL_HIGH_CREDX_BASE_ADDR(queue));
+
+       /* configure high credit */
+       value = readl(ioaddr + MTL_LOW_CREDX_BASE_ADDR(queue));
+       value &= ~MTL_HIGH_CRED_LC_MASK;
+       value |= low_credit & MTL_HIGH_CRED_LC_MASK;
+       writel(value, ioaddr + MTL_LOW_CREDX_BASE_ADDR(queue));
+}
+
 static void dwmac4_dump_regs(struct mac_device_info *hw, u32 *reg_space)
 {
        void __iomem *ioaddr = hw->pcsr;
@@ -566,6 +607,7 @@ static const struct stmmac_ops dwmac4_ops = {
        .prog_mtl_tx_algorithms = dwmac4_prog_mtl_tx_algorithms,
        .set_mtl_tx_queue_weight = dwmac4_set_mtl_tx_queue_weight,
        .map_mtl_to_dma = dwmac4_map_mtl_dma,
+       .config_cbs = dwmac4_config_cbs,
        .dump_regs = dwmac4_dump_regs,
        .host_irq_status = dwmac4_irq_status,
        .host_mtl_irq_status = dwmac4_irq_mtl_status,
index 2449487be53461c9d31b85c15f4c034430cf156a..915636ff2fc1d243c37e6c3e4c090847b87aae6b 100644 (file)
@@ -1670,6 +1670,31 @@ static void stmmac_set_tx_queue_weight(struct stmmac_priv *priv)
        }
 }
 
+/**
+ *  stmmac_configure_cbs - Configure CBS in TX queue
+ *  @priv: driver private structure
+ *  Description: It is used for configuring CBS in AVB TX queues
+ */
+static void stmmac_configure_cbs(struct stmmac_priv *priv)
+{
+       u32 tx_queues_count = priv->plat->tx_queues_to_use;
+       u32 mode_to_use;
+       u32 queue;
+
+       for (queue = 0; queue < tx_queues_count; queue++) {
+               mode_to_use = priv->plat->tx_queues_cfg[queue].mode_to_use;
+               if (mode_to_use == MTL_QUEUE_DCB)
+                       continue;
+
+               priv->hw->mac->config_cbs(priv->hw,
+                               priv->plat->tx_queues_cfg[queue].send_slope,
+                               priv->plat->tx_queues_cfg[queue].idle_slope,
+                               priv->plat->tx_queues_cfg[queue].high_credit,
+                               priv->plat->tx_queues_cfg[queue].low_credit,
+                               queue);
+       }
+}
+
 /**
  *  stmmac_rx_queue_dma_chan_map - Map RX queue to RX dma channel
  *  @priv: driver private structure
@@ -1710,6 +1735,10 @@ static void stmmac_mtl_configuration(struct stmmac_priv *priv)
                priv->hw->mac->prog_mtl_tx_algorithms(priv->hw,
                                                priv->plat->tx_sched_algorithm);
 
+       /* Configure CBS in AVB TX queues */
+       if (tx_queues_count > 1 && priv->hw->mac->config_cbs)
+               stmmac_configure_cbs(priv);
+
        /* Map RX MTL to DMA channels */
        if (rx_queues_count > 1 && priv->hw->mac->map_mtl_to_dma)
                stmmac_rx_queue_dma_chan_map(priv);
index 0b76e3de502d3b5255921a51425d420f9ec888c0..37f550ae76a54bb6ed7f26a176cf3957fc6f4f6b 100644 (file)
@@ -171,11 +171,11 @@ static void stmmac_mtl_setup(struct platform_device *pdev,
                        break;
 
                if (of_property_read_bool(q_node, "snps,dcb-algorithm"))
-                       plat->rx_queues_cfg[queue].mode_to_use = MTL_RX_DCB;
+                       plat->rx_queues_cfg[queue].mode_to_use = MTL_QUEUE_DCB;
                else if (of_property_read_bool(q_node, "snps,avb-algorithm"))
-                       plat->rx_queues_cfg[queue].mode_to_use = MTL_RX_AVB;
+                       plat->rx_queues_cfg[queue].mode_to_use = MTL_QUEUE_AVB;
                else
-                       plat->rx_queues_cfg[queue].mode_to_use = MTL_RX_DCB;
+                       plat->rx_queues_cfg[queue].mode_to_use = MTL_QUEUE_DCB;
 
                if (of_property_read_u8(q_node, "snps,map-to-dma-channel",
                                        &plat->rx_queues_cfg[queue].chan))
@@ -212,6 +212,29 @@ static void stmmac_mtl_setup(struct platform_device *pdev,
                                        &plat->tx_queues_cfg[queue].weight))
                        plat->tx_queues_cfg[queue].weight = 0x10 + queue;
 
+               if (of_property_read_bool(q_node, "snps,dcb-algorithm")) {
+                       plat->tx_queues_cfg[queue].mode_to_use = MTL_QUEUE_DCB;
+               } else if (of_property_read_bool(q_node,
+                                                "snps,avb-algorithm")) {
+                       plat->tx_queues_cfg[queue].mode_to_use = MTL_QUEUE_AVB;
+
+                       /* Credit Base Shaper parameters used by AVB */
+                       if (of_property_read_u32(q_node, "snps,send_slope",
+                               &plat->tx_queues_cfg[queue].send_slope))
+                               plat->tx_queues_cfg[queue].send_slope = 0x0;
+                       if (of_property_read_u32(q_node, "snps,idle_slope",
+                               &plat->tx_queues_cfg[queue].idle_slope))
+                               plat->tx_queues_cfg[queue].idle_slope = 0x0;
+                       if (of_property_read_u32(q_node, "snps,high_credit",
+                               &plat->tx_queues_cfg[queue].high_credit))
+                               plat->tx_queues_cfg[queue].high_credit = 0x0;
+                       if (of_property_read_u32(q_node, "snps,low_credit",
+                               &plat->tx_queues_cfg[queue].low_credit))
+                               plat->tx_queues_cfg[queue].low_credit = 0x0;
+               } else {
+                       plat->tx_queues_cfg[queue].mode_to_use = MTL_QUEUE_DCB;
+               }
+
                queue++;
        }
 
index 266ff2af91e5eca09b581c538f4674b5a5baf00b..be47b859e9548f8875e2f6a5a86657d69203a692 100644 (file)
@@ -55,9 +55,9 @@
 #define MTL_RX_ALGORITHM_SP    0x4
 #define MTL_RX_ALGORITHM_WSP   0x5
 
-/* RX Queue Mode */
-#define MTL_RX_DCB             0x0
-#define MTL_RX_AVB             0x1
+/* RX/TX Queue Mode */
+#define MTL_QUEUE_DCB          0x0
+#define MTL_QUEUE_AVB          0x1
 
 /* The MDC clock could be set higher than the IEEE 802.3
  * specified frequency limit 0f 2.5 MHz, by programming a clock divider
@@ -131,6 +131,12 @@ struct stmmac_rxq_cfg {
 
 struct stmmac_txq_cfg {
        u8 weight;
+       u8 mode_to_use;
+       /* Credit Base Shaper parameters */
+       u32 send_slope;
+       u32 idle_slope;
+       u32 high_credit;
+       u32 low_credit;
 };
 
 struct plat_stmmacenet_data {