aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ixgbe
diff options
context:
space:
mode:
authorYi Zou <yi.zou@intel.com>2009-11-06 07:56:00 -0500
committerDavid S. Miller <davem@davemloft.net>2009-11-06 23:33:36 -0500
commit26f23d82dd8eae6dcc2ab99c04a9256089576a73 (patch)
treee6e45270aacab63c8127e73fc8a50eb88cc56fea /drivers/net/ixgbe
parentb352e40da8977253f49850a24f6448653a459ac0 (diff)
ixgbe: Fix checking TFCS register for TXOFF status when DCB is enabled
When DCB is enabled, the ixgbe_check_tx_hang() should check the corresponding TC's TXOFF in TFCS based on the TC that the tx ring belongs to. Adds a function to map from the tx_ring hw reg_idx to the correspodning TC and read TFCS accordingly. Signed-off-by: Yi Zou <yi.zou@intel.com> Acked-by: Peter P Waskiewicz Jr <peter.p.waskiewicz.jr@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ixgbe')
-rw-r--r--drivers/net/ixgbe/ixgbe_main.c52
1 files changed, 51 insertions, 1 deletions
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index 26fc1df2b2e0..2d0f618b4a9d 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -226,6 +226,56 @@ static void ixgbe_unmap_and_free_tx_resource(struct ixgbe_adapter *adapter,
226 /* tx_buffer_info must be completely set up in the transmit path */ 226 /* tx_buffer_info must be completely set up in the transmit path */
227} 227}
228 228
229/**
230 * ixgbe_tx_is_paused - check if the tx ring is paused
231 * @adapter: the ixgbe adapter
232 * @tx_ring: the corresponding tx_ring
233 *
234 * If not in DCB mode, checks TFCS.TXOFF, otherwise, find out the
235 * corresponding TC of this tx_ring when checking TFCS.
236 *
237 * Returns : true if paused
238 */
239static inline bool ixgbe_tx_is_paused(struct ixgbe_adapter *adapter,
240 struct ixgbe_ring *tx_ring)
241{
242 int tc;
243 u32 txoff = IXGBE_TFCS_TXOFF;
244
245#ifdef CONFIG_IXGBE_DCB
246 if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
247 int reg_idx = tx_ring->reg_idx;
248 int dcb_i = adapter->ring_feature[RING_F_DCB].indices;
249
250 if (adapter->hw.mac.type == ixgbe_mac_82598EB) {
251 tc = reg_idx >> 2;
252 txoff = IXGBE_TFCS_TXOFF0;
253 } else if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
254 tc = 0;
255 txoff = IXGBE_TFCS_TXOFF;
256 if (dcb_i == 8) {
257 /* TC0, TC1 */
258 tc = reg_idx >> 5;
259 if (tc == 2) /* TC2, TC3 */
260 tc += (reg_idx - 64) >> 4;
261 else if (tc == 3) /* TC4, TC5, TC6, TC7 */
262 tc += 1 + ((reg_idx - 96) >> 3);
263 } else if (dcb_i == 4) {
264 /* TC0, TC1 */
265 tc = reg_idx >> 6;
266 if (tc == 1) {
267 tc += (reg_idx - 64) >> 5;
268 if (tc == 2) /* TC2, TC3 */
269 tc += (reg_idx - 96) >> 4;
270 }
271 }
272 }
273 txoff <<= tc;
274 }
275#endif
276 return IXGBE_READ_REG(&adapter->hw, IXGBE_TFCS) & txoff;
277}
278
229static inline bool ixgbe_check_tx_hang(struct ixgbe_adapter *adapter, 279static inline bool ixgbe_check_tx_hang(struct ixgbe_adapter *adapter,
230 struct ixgbe_ring *tx_ring, 280 struct ixgbe_ring *tx_ring,
231 unsigned int eop) 281 unsigned int eop)
@@ -237,7 +287,7 @@ static inline bool ixgbe_check_tx_hang(struct ixgbe_adapter *adapter,
237 adapter->detect_tx_hung = false; 287 adapter->detect_tx_hung = false;
238 if (tx_ring->tx_buffer_info[eop].time_stamp && 288 if (tx_ring->tx_buffer_info[eop].time_stamp &&
239 time_after(jiffies, tx_ring->tx_buffer_info[eop].time_stamp + HZ) && 289 time_after(jiffies, tx_ring->tx_buffer_info[eop].time_stamp + HZ) &&
240 !(IXGBE_READ_REG(&adapter->hw, IXGBE_TFCS) & IXGBE_TFCS_TXOFF)) { 290 !ixgbe_tx_is_paused(adapter, tx_ring)) {
241 /* detected Tx unit hang */ 291 /* detected Tx unit hang */
242 union ixgbe_adv_tx_desc *tx_desc; 292 union ixgbe_adv_tx_desc *tx_desc;
243 tx_desc = IXGBE_TX_DESC_ADV(*tx_ring, eop); 293 tx_desc = IXGBE_TX_DESC_ADV(*tx_ring, eop);