net: stmmac: TX and RX queue priority configuration
authorJoao Pinto <Joao.Pinto@synopsys.com>
Fri, 17 Mar 2017 16:11:06 +0000 (16:11 +0000)
committerDavid S. Miller <davem@davemloft.net>
Wed, 22 Mar 2017 00:24:01 +0000 (17:24 -0700)
This patch adds the configuration of RX and TX queues' priority.

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_pci.c
drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
include/linux/stmmac.h

index a7b0e41cb2647060b10ee68ab77cf532d9bce3c1..d11bd09f4ba6bba80510f47e2881c1eae3e14a02 100644 (file)
@@ -83,6 +83,7 @@ Optional properties:
                        - snps,dcb-algorithm: Queue to be enabled as DCB
                        - snps,avb-algorithm: Queue to be enabled as AVB
                - snps,map-to-dma-channel: Channel to map
+               - snps,priority: RX queue priority (Range: 0x0 to 0xF)
 - Multiple TX Queues parameters: below the list of all the parameters to
                                 configure the multiple TX queues:
        - snps,tx-queues-to-use: number of TX queues to be used in the driver
@@ -101,6 +102,7 @@ Optional properties:
                        - snps,idle_slope: unlock on WoL
                        - snps,high_credit: max write outstanding req. limit
                        - snps,low_credit: max read outstanding req. limit
+               - snps,priority: TX queue priority (Range: 0x0 to 0xF)
 Examples:
 
        stmmac_axi_setup: stmmac-axi-config {
@@ -115,6 +117,7 @@ Examples:
                queue0 {
                        snps,dcb-algorithm;
                        snps,map-to-dma-channel = <0x0>;
+                       snps,priority = <0x0>;
                };
        };
 
@@ -124,6 +127,7 @@ Examples:
                queue0 {
                        snps,weight = <0x10>;
                        snps,dcb-algorithm;
+                       snps,priority = <0x0>;
                };
 
                queue1 {
@@ -132,6 +136,7 @@ Examples:
                        snps,idle_slope = <0x1000>;
                        snps,high_credit = <0x3E800>;
                        snps,low_credit = <0xFFC18000>;
+                       snps,priority = <0x1>;
                };
        };
 
index badc4414d67b162a2e1c3cc3bdfd491be9225ada..e0b31e759c0eefb0baa6807d3e1427f02272f883 100644 (file)
@@ -469,6 +469,10 @@ struct stmmac_ops {
        int (*rx_ipc)(struct mac_device_info *hw);
        /* Enable RX Queues */
        void (*rx_queue_enable)(struct mac_device_info *hw, u8 mode, u32 queue);
+       /* RX Queues Priority */
+       void (*rx_queue_prio)(struct mac_device_info *hw, u32 prio, u32 queue);
+       /* TX Queues Priority */
+       void (*tx_queue_prio)(struct mac_device_info *hw, u32 prio, u32 queue);
        /* Program RX Algorithms */
        void (*prog_mtl_rx_algorithms)(struct mac_device_info *hw, u32 rx_alg);
        /* Program TX Algorithms */
index 54bcdb4d10dba88181309266fb2013308eae11d3..a6c382d22ebff6b90a6cddf2da6cc5fbacbabbd8 100644 (file)
 #define GMAC_HASH_TAB_32_63            0x00000014
 #define GMAC_RX_FLOW_CTRL              0x00000090
 #define GMAC_QX_TX_FLOW_CTRL(x)                (0x70 + x * 4)
+#define GMAC_TXQ_PRTY_MAP0             0x98
+#define GMAC_TXQ_PRTY_MAP1             0x9C
 #define GMAC_RXQ_CTRL0                 0x000000a0
+#define GMAC_RXQ_CTRL1                 0x000000a4
+#define GMAC_RXQ_CTRL2                 0x000000a8
+#define GMAC_RXQ_CTRL3                 0x000000ac
 #define GMAC_INT_STATUS                        0x000000b0
 #define GMAC_INT_EN                    0x000000b4
 #define GMAC_1US_TIC_COUNTER           0x000000dc
 /* MAC Flow Control RX */
 #define GMAC_RX_FLOW_CTRL_RFE          BIT(0)
 
+/* RX Queues Priorities */
+#define GMAC_RXQCTRL_PSRQX_MASK(x)     GENMASK(7 + ((x) * 8), 0 + ((x) * 8))
+#define GMAC_RXQCTRL_PSRQX_SHIFT(x)    ((x) * 8)
+
+/* TX Queues Priorities */
+#define GMAC_TXQCTRL_PSTQX_MASK(x)     GENMASK(7 + ((x) * 8), 0 + ((x) * 8))
+#define GMAC_TXQCTRL_PSTQX_SHIFT(x)    ((x) * 8)
+
 /* MAC Flow Control TX */
 #define GMAC_TX_FLOW_CTRL_TFE          BIT(1)
 #define GMAC_TX_FLOW_CTRL_PT_SHIFT     16
index 10599dbc232fbda9684ed46a9fd24d2294a548f5..342f62abb9cad5346a92698aa7ea7d9203106869 100644 (file)
@@ -74,6 +74,41 @@ static void dwmac4_rx_queue_enable(struct mac_device_info *hw,
        writel(value, ioaddr + GMAC_RXQ_CTRL0);
 }
 
+static void dwmac4_rx_queue_priority(struct mac_device_info *hw,
+                                    u32 prio, u32 queue)
+{
+       void __iomem *ioaddr = hw->pcsr;
+       u32 base_register;
+       u32 value;
+
+       base_register = (queue < 4) ? GMAC_RXQ_CTRL2 : GMAC_RXQ_CTRL3;
+
+       value = readl(ioaddr + base_register);
+
+       value &= ~GMAC_RXQCTRL_PSRQX_MASK(queue);
+       value |= (prio << GMAC_RXQCTRL_PSRQX_SHIFT(queue)) &
+                                               GMAC_RXQCTRL_PSRQX_MASK(queue);
+       writel(value, ioaddr + base_register);
+}
+
+static void dwmac4_tx_queue_priority(struct mac_device_info *hw,
+                                    u32 prio, u32 queue)
+{
+       void __iomem *ioaddr = hw->pcsr;
+       u32 base_register;
+       u32 value;
+
+       base_register = (queue < 4) ? GMAC_TXQ_PRTY_MAP0 : GMAC_TXQ_PRTY_MAP1;
+
+       value = readl(ioaddr + base_register);
+
+       value &= ~GMAC_TXQCTRL_PSTQX_MASK(queue);
+       value |= (prio << GMAC_TXQCTRL_PSTQX_SHIFT(queue)) &
+                                               GMAC_TXQCTRL_PSTQX_MASK(queue);
+
+       writel(value, ioaddr + base_register);
+}
+
 static void dwmac4_prog_mtl_rx_algorithms(struct mac_device_info *hw,
                                          u32 rx_alg)
 {
@@ -603,6 +638,8 @@ static const struct stmmac_ops dwmac4_ops = {
        .core_init = dwmac4_core_init,
        .rx_ipc = dwmac4_rx_ipc_enable,
        .rx_queue_enable = dwmac4_rx_queue_enable,
+       .rx_queue_prio = dwmac4_rx_queue_priority,
+       .tx_queue_prio = dwmac4_tx_queue_priority,
        .prog_mtl_rx_algorithms = dwmac4_prog_mtl_rx_algorithms,
        .prog_mtl_tx_algorithms = dwmac4_prog_mtl_tx_algorithms,
        .set_mtl_tx_queue_weight = dwmac4_set_mtl_tx_queue_weight,
index a389dfbe630c2aa089a28e2ef231fb4fa4aed6fa..0f2c0d762e334838d408a50408fb6d816f8e60b7 100644 (file)
@@ -2292,6 +2292,46 @@ static void stmmac_rx_queue_dma_chan_map(struct stmmac_priv *priv)
        }
 }
 
+/**
+ *  stmmac_mac_config_rx_queues_prio - Configure RX Queue priority
+ *  @priv: driver private structure
+ *  Description: It is used for configuring the RX Queue Priority
+ */
+static void stmmac_mac_config_rx_queues_prio(struct stmmac_priv *priv)
+{
+       u32 rx_queues_count = priv->plat->rx_queues_to_use;
+       u32 queue;
+       u32 prio;
+
+       for (queue = 0; queue < rx_queues_count; queue++) {
+               if (!priv->plat->rx_queues_cfg[queue].use_prio)
+                       continue;
+
+               prio = priv->plat->rx_queues_cfg[queue].prio;
+               priv->hw->mac->rx_queue_prio(priv->hw, prio, queue);
+       }
+}
+
+/**
+ *  stmmac_mac_config_tx_queues_prio - Configure TX Queue priority
+ *  @priv: driver private structure
+ *  Description: It is used for configuring the TX Queue Priority
+ */
+static void stmmac_mac_config_tx_queues_prio(struct stmmac_priv *priv)
+{
+       u32 tx_queues_count = priv->plat->tx_queues_to_use;
+       u32 queue;
+       u32 prio;
+
+       for (queue = 0; queue < tx_queues_count; queue++) {
+               if (!priv->plat->tx_queues_cfg[queue].use_prio)
+                       continue;
+
+               prio = priv->plat->tx_queues_cfg[queue].prio;
+               priv->hw->mac->tx_queue_prio(priv->hw, prio, queue);
+       }
+}
+
 /**
  *  stmmac_mtl_configuration - Configure MTL
  *  @priv: driver private structure
@@ -2329,6 +2369,14 @@ static void stmmac_mtl_configuration(struct stmmac_priv *priv)
 
        /* Set the HW DMA mode and the COE */
        stmmac_dma_operation_mode(priv);
+
+       /* Set RX priorities */
+       if (rx_queues_count > 1 && priv->hw->mac->rx_queue_prio)
+               stmmac_mac_config_rx_queues_prio(priv);
+
+       /* Set TX priorities */
+       if (tx_queues_count > 1 && priv->hw->mac->tx_queue_prio)
+               stmmac_mac_config_tx_queues_prio(priv);
 }
 
 /**
index cea472a7c335e561082d42827579697fa1bacbef..ffe4fac22d3d4f04fb8dd4cadc9e7b1bff04e720 100644 (file)
@@ -92,6 +92,10 @@ static void stmmac_default_data(struct plat_stmmacenet_data *plat)
        /* Set default number of RX and TX queues to use */
        plat->tx_queues_to_use = 1;
        plat->rx_queues_to_use = 1;
+
+       /* Disable Priority config by default */
+       plat->tx_queues_cfg[0].use_prio = false;
+       plat->rx_queues_cfg[0].use_prio = false;
 }
 
 static int quark_default_data(struct plat_stmmacenet_data *plat,
index 37f550ae76a54bb6ed7f26a176cf3957fc6f4f6b..77b0468dd79fabcaf44471888251ad2342c81c9b 100644 (file)
@@ -182,6 +182,14 @@ static void stmmac_mtl_setup(struct platform_device *pdev,
                        plat->rx_queues_cfg[queue].chan = queue;
                /* TODO: Dynamic mapping to be included in the future */
 
+               if (of_property_read_u32(q_node, "snps,priority",
+                                       &plat->rx_queues_cfg[queue].prio)) {
+                       plat->rx_queues_cfg[queue].prio = 0;
+                       plat->rx_queues_cfg[queue].use_prio = false;
+               } else {
+                       plat->rx_queues_cfg[queue].use_prio = true;
+               }
+
                queue++;
        }
 
@@ -235,6 +243,14 @@ static void stmmac_mtl_setup(struct platform_device *pdev,
                        plat->tx_queues_cfg[queue].mode_to_use = MTL_QUEUE_DCB;
                }
 
+               if (of_property_read_u32(q_node, "snps,priority",
+                                       &plat->tx_queues_cfg[queue].prio)) {
+                       plat->tx_queues_cfg[queue].prio = 0;
+                       plat->tx_queues_cfg[queue].use_prio = false;
+               } else {
+                       plat->tx_queues_cfg[queue].use_prio = true;
+               }
+
                queue++;
        }
 
index be47b859e9548f8875e2f6a5a86657d69203a692..b7d5e7ae95914d4873691fa3d2247ab5de5cdf83 100644 (file)
@@ -127,6 +127,8 @@ struct stmmac_axi {
 struct stmmac_rxq_cfg {
        u8 mode_to_use;
        u8 chan;
+       bool use_prio;
+       u32 prio;
 };
 
 struct stmmac_txq_cfg {
@@ -137,6 +139,8 @@ struct stmmac_txq_cfg {
        u32 idle_slope;
        u32 high_credit;
        u32 low_credit;
+       bool use_prio;
+       u32 prio;
 };
 
 struct plat_stmmacenet_data {