igb: Only change Tx arbitration when CBS is on
authorJesus Sanchez-Palencia <jesus.sanchez-palencia@intel.com>
Tue, 3 Jul 2018 22:42:56 +0000 (15:42 -0700)
committerDavid S. Miller <davem@davemloft.net>
Wed, 4 Jul 2018 13:30:28 +0000 (22:30 +0900)
Currently the data transmission arbitration algorithm - DataTranARB
field on TQAVCTRL reg - is always set to CBS when the Tx mode is
changed from legacy to 'Qav' mode.

Make that configuration a bit more granular in preparation for the
upcoming Launchtime enabling patches, since CBS and Launchtime can be
enabled separately. That is achieved by moving the DataTranARB setup
to igb_config_tx_modes() instead.

Similarly, when disabling CBS we must check if it has been disabled
for all queues, and clear the DataTranARB accordingly.

Signed-off-by: Jesus Sanchez-Palencia <jesus.sanchez-palencia@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/intel/igb/igb_main.c

index 15f6b9c57ccf09ecb447c96d51b1c4e420e3c88b..8c90f1e51addf3b18eb3c8dfd3c2e0252301208e 100644 (file)
@@ -1654,6 +1654,18 @@ static void set_queue_mode(struct e1000_hw *hw, int queue, enum queue_mode mode)
        wr32(E1000_I210_TQAVCC(queue), val);
 }
 
+static bool is_any_cbs_enabled(struct igb_adapter *adapter)
+{
+       int i;
+
+       for (i = 0; i < adapter->num_tx_queues; i++) {
+               if (adapter->tx_ring[i]->cbs_enable)
+                       return true;
+       }
+
+       return false;
+}
+
 /**
  *  igb_config_tx_modes - Configure "Qav Tx mode" features on igb
  *  @adapter: pointer to adapter struct
@@ -1668,7 +1680,7 @@ static void igb_config_tx_modes(struct igb_adapter *adapter, int queue)
        struct igb_ring *ring = adapter->tx_ring[queue];
        struct net_device *netdev = adapter->netdev;
        struct e1000_hw *hw = &adapter->hw;
-       u32 tqavcc;
+       u32 tqavcc, tqavctrl;
        u16 value;
 
        WARN_ON(hw->mac.type != e1000_i210);
@@ -1693,6 +1705,14 @@ static void igb_config_tx_modes(struct igb_adapter *adapter, int queue)
                set_tx_desc_fetch_prio(hw, queue, TX_QUEUE_PRIO_HIGH);
                set_queue_mode(hw, queue, QUEUE_MODE_STREAM_RESERVATION);
 
+               /* Always set data transfer arbitration to credit-based
+                * shaper algorithm on TQAVCTRL if CBS is enabled for any of
+                * the queues.
+                */
+               tqavctrl = rd32(E1000_I210_TQAVCTRL);
+               tqavctrl |= E1000_TQAVCTRL_DATATRANARB;
+               wr32(E1000_I210_TQAVCTRL, tqavctrl);
+
                /* According to i210 datasheet section 7.2.7.7, we should set
                 * the 'idleSlope' field from TQAVCC register following the
                 * equation:
@@ -1770,6 +1790,16 @@ static void igb_config_tx_modes(struct igb_adapter *adapter, int queue)
 
                /* Set hiCredit to zero. */
                wr32(E1000_I210_TQAVHC(queue), 0);
+
+               /* If CBS is not enabled for any queues anymore, then return to
+                * the default state of Data Transmission Arbitration on
+                * TQAVCTRL.
+                */
+               if (!is_any_cbs_enabled(adapter)) {
+                       tqavctrl = rd32(E1000_I210_TQAVCTRL);
+                       tqavctrl &= ~E1000_TQAVCTRL_DATATRANARB;
+                       wr32(E1000_I210_TQAVCTRL, tqavctrl);
+               }
        }
 
        /* XXX: In i210 controller the sendSlope and loCredit parameters from
@@ -1803,18 +1833,6 @@ static int igb_save_cbs_params(struct igb_adapter *adapter, int queue,
        return 0;
 }
 
-static bool is_any_cbs_enabled(struct igb_adapter *adapter)
-{
-       int i;
-
-       for (i = 0; i < adapter->num_tx_queues; i++) {
-               if (adapter->tx_ring[i]->cbs_enable)
-                       return true;
-       }
-
-       return false;
-}
-
 /**
  *  igb_setup_tx_mode - Switch to/from Qav Tx mode when applicable
  *  @adapter: pointer to adapter struct
@@ -1838,11 +1856,10 @@ static void igb_setup_tx_mode(struct igb_adapter *adapter)
                int i, max_queue;
 
                /* Configure TQAVCTRL register: set transmit mode to 'Qav',
-                * set data fetch arbitration to 'round robin' and set data
-                * transfer arbitration to 'credit shaper algorithm.
+                * set data fetch arbitration to 'round robin'.
                 */
                val = rd32(E1000_I210_TQAVCTRL);
-               val |= E1000_TQAVCTRL_XMIT_MODE | E1000_TQAVCTRL_DATATRANARB;
+               val |= E1000_TQAVCTRL_XMIT_MODE;
                val &= ~E1000_TQAVCTRL_DATAFETCHARB;
                wr32(E1000_I210_TQAVCTRL, val);