net: stmmac: RX queue routing configuration
authorJoao Pinto <Joao.Pinto@synopsys.com>
Fri, 17 Mar 2017 16:11:07 +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 queues' routing.

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 d11bd09f4ba6bba80510f47e2881c1eae3e14a02..784d98862b5209ebf32df17e405910b983d1eb80 100644 (file)
@@ -83,6 +83,12 @@ 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
+               - Specifiy specific packet routing:
+                       - snps,route-avcp: AV Untagged Control packets
+                       - snps,route-ptp: PTP Packets
+                       - snps,route-dcbcp: DCB Control Packets
+                       - snps,route-up: Untagged Packets
+                       - snps,route-multi-broad: Multicast & Broadcast Packets
                - 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:
index e0b31e759c0eefb0baa6807d3e1427f02272f883..572cf8b617070367c73c9d279f5de1b825ac6e63 100644 (file)
@@ -246,6 +246,15 @@ struct stmmac_extra_stats {
 #define STMMAC_TX_MAX_FRAMES   256
 #define STMMAC_TX_FRAMES       64
 
+/* Packets types */
+enum packets_types {
+       PACKET_AVCPQ = 0x1, /* AV Untagged Control packets */
+       PACKET_PTPQ = 0x2, /* PTP Packets */
+       PACKET_DCBCPQ = 0x3, /* DCB Control Packets */
+       PACKET_UPQ = 0x4, /* Untagged Packets */
+       PACKET_MCBCQ = 0x5, /* Multicast & Broadcast Packets */
+};
+
 /* Rx IPC status */
 enum rx_frame_status {
        good_frame = 0x0,
@@ -473,6 +482,9 @@ struct stmmac_ops {
        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);
+       /* RX Queues Routing */
+       void (*rx_queue_routing)(struct mac_device_info *hw, u8 packet,
+                                u32 queue);
        /* Program RX Algorithms */
        void (*prog_mtl_rx_algorithms)(struct mac_device_info *hw, u32 rx_alg);
        /* Program TX Algorithms */
@@ -581,6 +593,11 @@ struct mac_device_info {
        unsigned int ps;
 };
 
+struct stmmac_rx_routing {
+       u32 reg_mask;
+       u32 reg_shift;
+};
+
 struct mac_device_info *dwmac1000_setup(void __iomem *ioaddr, int mcbins,
                                        int perfect_uc_entries,
                                        int *synopsys_id);
index a6c382d22ebff6b90a6cddf2da6cc5fbacbabbd8..d74cedf2a397580aeb6c62737a35030e65053367 100644 (file)
 #define GMAC_ADDR_HIGH(reg)            (0x300 + reg * 8)
 #define GMAC_ADDR_LOW(reg)             (0x304 + reg * 8)
 
+/* RX Queues Routing */
+#define GMAC_RXQCTRL_AVCPQ_MASK                GENMASK(2, 0)
+#define GMAC_RXQCTRL_AVCPQ_SHIFT       0
+#define GMAC_RXQCTRL_PTPQ_MASK         GENMASK(6, 4)
+#define GMAC_RXQCTRL_PTPQ_SHIFT                4
+#define GMAC_RXQCTRL_DCBCPQ_MASK       GENMASK(10, 8)
+#define GMAC_RXQCTRL_DCBCPQ_SHIFT      8
+#define GMAC_RXQCTRL_UPQ_MASK          GENMASK(14, 12)
+#define GMAC_RXQCTRL_UPQ_SHIFT         12
+#define GMAC_RXQCTRL_MCBCQ_MASK                GENMASK(18, 16)
+#define GMAC_RXQCTRL_MCBCQ_SHIFT       16
+#define GMAC_RXQCTRL_MCBCQEN           BIT(20)
+#define GMAC_RXQCTRL_MCBCQEN_SHIFT     20
+#define GMAC_RXQCTRL_TACPQE            BIT(21)
+#define GMAC_RXQCTRL_TACPQE_SHIFT      21
+
 /* MAC Packet Filtering */
 #define GMAC_PACKET_FILTER_PR          BIT(0)
 #define GMAC_PACKET_FILTER_HMC         BIT(2)
index 342f62abb9cad5346a92698aa7ea7d9203106869..40ce202184025b5e393eccf60cd9aa06dfd4bcbd 100644 (file)
@@ -109,6 +109,39 @@ static void dwmac4_tx_queue_priority(struct mac_device_info *hw,
        writel(value, ioaddr + base_register);
 }
 
+static void dwmac4_tx_queue_routing(struct mac_device_info *hw,
+                                   u8 packet, u32 queue)
+{
+       void __iomem *ioaddr = hw->pcsr;
+       u32 value;
+
+       const struct stmmac_rx_routing route_possibilities[] = {
+               { GMAC_RXQCTRL_AVCPQ_MASK, GMAC_RXQCTRL_AVCPQ_SHIFT },
+               { GMAC_RXQCTRL_PTPQ_MASK, GMAC_RXQCTRL_PTPQ_SHIFT },
+               { GMAC_RXQCTRL_DCBCPQ_MASK, GMAC_RXQCTRL_DCBCPQ_SHIFT },
+               { GMAC_RXQCTRL_UPQ_MASK, GMAC_RXQCTRL_UPQ_SHIFT },
+               { GMAC_RXQCTRL_MCBCQ_MASK, GMAC_RXQCTRL_MCBCQ_SHIFT },
+       };
+
+       value = readl(ioaddr + GMAC_RXQ_CTRL1);
+
+       /* routing configuration */
+       value &= ~route_possibilities[packet - 1].reg_mask;
+       value |= (queue << route_possibilities[packet-1].reg_shift) &
+                route_possibilities[packet - 1].reg_mask;
+
+       /* some packets require extra ops */
+       if (packet == PACKET_AVCPQ) {
+               value &= ~GMAC_RXQCTRL_TACPQE;
+               value |= 0x1 << GMAC_RXQCTRL_TACPQE_SHIFT;
+       } else if (packet == PACKET_MCBCQ) {
+               value &= ~GMAC_RXQCTRL_MCBCQEN;
+               value |= 0x1 << GMAC_RXQCTRL_MCBCQEN_SHIFT;
+       }
+
+       writel(value, ioaddr + GMAC_RXQ_CTRL1);
+}
+
 static void dwmac4_prog_mtl_rx_algorithms(struct mac_device_info *hw,
                                          u32 rx_alg)
 {
@@ -640,6 +673,7 @@ static const struct stmmac_ops dwmac4_ops = {
        .rx_queue_enable = dwmac4_rx_queue_enable,
        .rx_queue_prio = dwmac4_rx_queue_priority,
        .tx_queue_prio = dwmac4_tx_queue_priority,
+       .rx_queue_routing = dwmac4_tx_queue_routing,
        .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 0f2c0d762e334838d408a50408fb6d816f8e60b7..531bf1dc35cd223f8aa6d0a53e7ef563b3f9dde0 100644 (file)
@@ -2332,6 +2332,27 @@ static void stmmac_mac_config_tx_queues_prio(struct stmmac_priv *priv)
        }
 }
 
+/**
+ *  stmmac_mac_config_rx_queues_routing - Configure RX Queue Routing
+ *  @priv: driver private structure
+ *  Description: It is used for configuring the RX queue routing
+ */
+static void stmmac_mac_config_rx_queues_routing(struct stmmac_priv *priv)
+{
+       u32 rx_queues_count = priv->plat->rx_queues_to_use;
+       u32 queue;
+       u8 packet;
+
+       for (queue = 0; queue < rx_queues_count; queue++) {
+               /* no specific packet type routing specified for the queue */
+               if (priv->plat->rx_queues_cfg[queue].pkt_route == 0x0)
+                       continue;
+
+               packet = priv->plat->rx_queues_cfg[queue].pkt_route;
+               priv->hw->mac->rx_queue_prio(priv->hw, packet, queue);
+       }
+}
+
 /**
  *  stmmac_mtl_configuration - Configure MTL
  *  @priv: driver private structure
@@ -2377,6 +2398,10 @@ static void stmmac_mtl_configuration(struct stmmac_priv *priv)
        /* Set TX priorities */
        if (tx_queues_count > 1 && priv->hw->mac->tx_queue_prio)
                stmmac_mac_config_tx_queues_prio(priv);
+
+       /* Set RX routing */
+       if (rx_queues_count > 1 && priv->hw->mac->rx_queue_routing)
+               stmmac_mac_config_rx_queues_routing(priv);
 }
 
 /**
index ffe4fac22d3d4f04fb8dd4cadc9e7b1bff04e720..a224d7bf1c1beea57fe976cbd4f94f63603a480a 100644 (file)
@@ -96,6 +96,9 @@ static void stmmac_default_data(struct plat_stmmacenet_data *plat)
        /* Disable Priority config by default */
        plat->tx_queues_cfg[0].use_prio = false;
        plat->rx_queues_cfg[0].use_prio = false;
+
+       /* Disable RX queues routing by default */
+       plat->rx_queues_cfg[0].pkt_route = 0x0;
 }
 
 static int quark_default_data(struct plat_stmmacenet_data *plat,
index 77b0468dd79fabcaf44471888251ad2342c81c9b..f5c8b1bca002ea8e08c3e22a859c38d46b12c3b1 100644 (file)
@@ -190,6 +190,20 @@ static void stmmac_mtl_setup(struct platform_device *pdev,
                        plat->rx_queues_cfg[queue].use_prio = true;
                }
 
+               /* RX queue specific packet type routing */
+               if (of_property_read_bool(q_node, "snps,route-avcp"))
+                       plat->rx_queues_cfg[queue].pkt_route = PACKET_AVCPQ;
+               else if (of_property_read_bool(q_node, "snps,route-ptp"))
+                       plat->rx_queues_cfg[queue].pkt_route = PACKET_PTPQ;
+               else if (of_property_read_bool(q_node, "snps,route-dcbcp"))
+                       plat->rx_queues_cfg[queue].pkt_route = PACKET_DCBCPQ;
+               else if (of_property_read_bool(q_node, "snps,route-up"))
+                       plat->rx_queues_cfg[queue].pkt_route = PACKET_UPQ;
+               else if (of_property_read_bool(q_node, "snps,route-multi-broad"))
+                       plat->rx_queues_cfg[queue].pkt_route = PACKET_MCBCQ;
+               else
+                       plat->rx_queues_cfg[queue].pkt_route = 0x0;
+
                queue++;
        }
 
index b7d5e7ae95914d4873691fa3d2247ab5de5cdf83..cd98ee232ad1911da969dafd5c151482c7526868 100644 (file)
@@ -127,6 +127,7 @@ struct stmmac_axi {
 struct stmmac_rxq_cfg {
        u8 mode_to_use;
        u8 chan;
+       u8 pkt_route;
        bool use_prio;
        u32 prio;
 };