net: stmmac: Implement RX Coalesce Frames setting
authorJose Abreu <Jose.Abreu@synopsys.com>
Tue, 9 Jul 2019 08:02:58 +0000 (10:02 +0200)
committerDavid S. Miller <davem@davemloft.net>
Tue, 9 Jul 2019 19:20:08 +0000 (12:20 -0700)
Add support for coalescing RX path by specifying number of frames which
don't need to have interrupt on completion bit set.

This is only available when RX Watchdog is enabled.

Acked-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Signed-off-by: Jose Abreu <joabreu@synopsys.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/stmicro/stmmac/common.h
drivers/net/ethernet/stmicro/stmmac/stmmac.h
drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c

index 2403a65167b27ea429656b092cc6ee10874be43b..dfd47fdfa4470aac44601f082036ef95c522610a 100644 (file)
@@ -252,6 +252,7 @@ struct stmmac_safety_stats {
 #define STMMAC_MAX_COAL_TX_TICK        100000
 #define STMMAC_TX_MAX_FRAMES   256
 #define STMMAC_TX_FRAMES       1
+#define STMMAC_RX_FRAMES       25
 
 /* Packets types */
 enum packets_types {
index 123898235cb0664f6ad9b2af58609e90925fc510..513f4e2df5f613cf0adac7515e2d32a54e2d6de0 100644 (file)
@@ -55,6 +55,7 @@ struct stmmac_tx_queue {
 };
 
 struct stmmac_rx_queue {
+       u32 rx_count_frames;
        u32 queue_index;
        struct stmmac_priv *priv_data;
        struct dma_extended_desc *dma_erx;
@@ -110,6 +111,7 @@ struct stmmac_priv {
        /* Frequently used values are kept adjacent for cache effect */
        u32 tx_coal_frames;
        u32 tx_coal_timer;
+       u32 rx_coal_frames;
 
        int tx_coalesce;
        int hwts_tx_en;
index cfd93eefb50ecc5dfc50ed6b8c51d43c5c5b9a87..6efb66820d4cb40dec095e43e633f8abbd772faa 100644 (file)
@@ -701,8 +701,10 @@ static int stmmac_get_coalesce(struct net_device *dev,
        ec->tx_coalesce_usecs = priv->tx_coal_timer;
        ec->tx_max_coalesced_frames = priv->tx_coal_frames;
 
-       if (priv->use_riwt)
+       if (priv->use_riwt) {
+               ec->rx_max_coalesced_frames = priv->rx_coal_frames;
                ec->rx_coalesce_usecs = stmmac_riwt2usec(priv->rx_riwt, priv);
+       }
 
        return 0;
 }
@@ -715,7 +717,7 @@ static int stmmac_set_coalesce(struct net_device *dev,
        unsigned int rx_riwt;
 
        /* Check not supported parameters  */
-       if ((ec->rx_max_coalesced_frames) || (ec->rx_coalesce_usecs_irq) ||
+       if ((ec->rx_coalesce_usecs_irq) ||
            (ec->rx_max_coalesced_frames_irq) || (ec->tx_coalesce_usecs_irq) ||
            (ec->use_adaptive_rx_coalesce) || (ec->use_adaptive_tx_coalesce) ||
            (ec->pkt_rate_low) || (ec->rx_coalesce_usecs_low) ||
@@ -749,6 +751,7 @@ static int stmmac_set_coalesce(struct net_device *dev,
        /* Only copy relevant parameters, ignore all others. */
        priv->tx_coal_frames = ec->tx_max_coalesced_frames;
        priv->tx_coal_timer = ec->tx_coalesce_usecs;
+       priv->rx_coal_frames = ec->rx_max_coalesced_frames;
        priv->rx_riwt = rx_riwt;
        stmmac_rx_watchdog(priv, priv->ioaddr, priv->rx_riwt, rx_cnt);
 
index bdedde99148a034d90807d4981cfbb420a5d958c..c142e9367a6801f544ac70205bfe2adbb434bc12 100644 (file)
@@ -2268,20 +2268,21 @@ static void stmmac_tx_timer(struct timer_list *t)
 }
 
 /**
- * stmmac_init_tx_coalesce - init tx mitigation options.
+ * stmmac_init_coalesce - init mitigation options.
  * @priv: driver private structure
  * Description:
- * This inits the transmit coalesce parameters: i.e. timer rate,
+ * This inits the coalesce parameters: i.e. timer rate,
  * timer handler and default threshold used for enabling the
  * interrupt on completion bit.
  */
-static void stmmac_init_tx_coalesce(struct stmmac_priv *priv)
+static void stmmac_init_coalesce(struct stmmac_priv *priv)
 {
        u32 tx_channel_count = priv->plat->tx_queues_to_use;
        u32 chan;
 
        priv->tx_coal_frames = STMMAC_TX_FRAMES;
        priv->tx_coal_timer = STMMAC_COAL_TX_TIMER;
+       priv->rx_coal_frames = STMMAC_RX_FRAMES;
 
        for (chan = 0; chan < tx_channel_count; chan++) {
                struct stmmac_tx_queue *tx_q = &priv->tx_queue[chan];
@@ -2651,7 +2652,7 @@ static int stmmac_open(struct net_device *dev)
                goto init_error;
        }
 
-       stmmac_init_tx_coalesce(priv);
+       stmmac_init_coalesce(priv);
 
        phylink_start(priv->phylink);
 
@@ -3289,6 +3290,7 @@ static inline void stmmac_rx_refill(struct stmmac_priv *priv, u32 queue)
 
        while (dirty-- > 0) {
                struct dma_desc *p;
+               bool use_rx_wd;
 
                if (priv->extend_desc)
                        p = (struct dma_desc *)(rx_q->dma_erx + entry);
@@ -3331,7 +3333,11 @@ static inline void stmmac_rx_refill(struct stmmac_priv *priv, u32 queue)
                }
                dma_wmb();
 
-               stmmac_set_rx_owner(priv, p, priv->use_riwt);
+               rx_q->rx_count_frames++;
+               rx_q->rx_count_frames %= priv->rx_coal_frames;
+               use_rx_wd = priv->use_riwt && rx_q->rx_count_frames;
+
+               stmmac_set_rx_owner(priv, p, use_rx_wd);
 
                dma_wmb();
 
@@ -4631,7 +4637,7 @@ int stmmac_resume(struct device *dev)
        stmmac_clear_descriptors(priv);
 
        stmmac_hw_setup(ndev, false);
-       stmmac_init_tx_coalesce(priv);
+       stmmac_init_coalesce(priv);
        stmmac_set_rx_mode(ndev);
 
        stmmac_enable_all_queues(priv);