Commit 0364a0d0 authored by Jesus Sanchez-Palencia's avatar Jesus Sanchez-Palencia Committed by David S. Miller

igb: Only change Tx arbitration when CBS is on

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: default avatarJesus Sanchez-Palencia <jesus.sanchez-palencia@intel.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 91db3642
...@@ -1654,6 +1654,18 @@ static void set_queue_mode(struct e1000_hw *hw, int queue, enum queue_mode mode) ...@@ -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); 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 * igb_config_tx_modes - Configure "Qav Tx mode" features on igb
* @adapter: pointer to adapter struct * @adapter: pointer to adapter struct
...@@ -1668,7 +1680,7 @@ static void igb_config_tx_modes(struct igb_adapter *adapter, int queue) ...@@ -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 igb_ring *ring = adapter->tx_ring[queue];
struct net_device *netdev = adapter->netdev; struct net_device *netdev = adapter->netdev;
struct e1000_hw *hw = &adapter->hw; struct e1000_hw *hw = &adapter->hw;
u32 tqavcc; u32 tqavcc, tqavctrl;
u16 value; u16 value;
WARN_ON(hw->mac.type != e1000_i210); WARN_ON(hw->mac.type != e1000_i210);
...@@ -1693,6 +1705,14 @@ static void igb_config_tx_modes(struct igb_adapter *adapter, int queue) ...@@ -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_tx_desc_fetch_prio(hw, queue, TX_QUEUE_PRIO_HIGH);
set_queue_mode(hw, queue, QUEUE_MODE_STREAM_RESERVATION); 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 /* According to i210 datasheet section 7.2.7.7, we should set
* the 'idleSlope' field from TQAVCC register following the * the 'idleSlope' field from TQAVCC register following the
* equation: * equation:
...@@ -1770,6 +1790,16 @@ static void igb_config_tx_modes(struct igb_adapter *adapter, int queue) ...@@ -1770,6 +1790,16 @@ static void igb_config_tx_modes(struct igb_adapter *adapter, int queue)
/* Set hiCredit to zero. */ /* Set hiCredit to zero. */
wr32(E1000_I210_TQAVHC(queue), 0); 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 /* 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, ...@@ -1803,18 +1833,6 @@ static int igb_save_cbs_params(struct igb_adapter *adapter, int queue,
return 0; 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 * igb_setup_tx_mode - Switch to/from Qav Tx mode when applicable
* @adapter: pointer to adapter struct * @adapter: pointer to adapter struct
...@@ -1838,11 +1856,10 @@ static void igb_setup_tx_mode(struct igb_adapter *adapter) ...@@ -1838,11 +1856,10 @@ static void igb_setup_tx_mode(struct igb_adapter *adapter)
int i, max_queue; int i, max_queue;
/* Configure TQAVCTRL register: set transmit mode to 'Qav', /* Configure TQAVCTRL register: set transmit mode to 'Qav',
* set data fetch arbitration to 'round robin' and set data * set data fetch arbitration to 'round robin'.
* transfer arbitration to 'credit shaper algorithm.
*/ */
val = rd32(E1000_I210_TQAVCTRL); val = rd32(E1000_I210_TQAVCTRL);
val |= E1000_TQAVCTRL_XMIT_MODE | E1000_TQAVCTRL_DATATRANARB; val |= E1000_TQAVCTRL_XMIT_MODE;
val &= ~E1000_TQAVCTRL_DATAFETCHARB; val &= ~E1000_TQAVCTRL_DATAFETCHARB;
wr32(E1000_I210_TQAVCTRL, val); wr32(E1000_I210_TQAVCTRL, val);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment