aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ixgbe/ixgbe_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ixgbe/ixgbe_main.c')
-rw-r--r--drivers/net/ixgbe/ixgbe_main.c60
1 files changed, 23 insertions, 37 deletions
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index 850361a4c38d..8e270b63e806 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -204,9 +204,6 @@ static inline bool ixgbe_check_tx_hang(struct ixgbe_adapter *adapter,
204#define DESC_NEEDED (TXD_USE_COUNT(IXGBE_MAX_DATA_PER_TXD) /* skb->data */ + \ 204#define DESC_NEEDED (TXD_USE_COUNT(IXGBE_MAX_DATA_PER_TXD) /* skb->data */ + \
205 MAX_SKB_FRAGS * TXD_USE_COUNT(PAGE_SIZE) + 1) /* for context */ 205 MAX_SKB_FRAGS * TXD_USE_COUNT(PAGE_SIZE) + 1) /* for context */
206 206
207#define GET_TX_HEAD_FROM_RING(ring) (\
208 *(volatile u32 *) \
209 ((union ixgbe_adv_tx_desc *)(ring)->desc + (ring)->count))
210static void ixgbe_tx_timeout(struct net_device *netdev); 207static void ixgbe_tx_timeout(struct net_device *netdev);
211 208
212/** 209/**
@@ -217,26 +214,27 @@ static void ixgbe_tx_timeout(struct net_device *netdev);
217static bool ixgbe_clean_tx_irq(struct ixgbe_adapter *adapter, 214static bool ixgbe_clean_tx_irq(struct ixgbe_adapter *adapter,
218 struct ixgbe_ring *tx_ring) 215 struct ixgbe_ring *tx_ring)
219{ 216{
220 union ixgbe_adv_tx_desc *tx_desc;
221 struct ixgbe_tx_buffer *tx_buffer_info;
222 struct net_device *netdev = adapter->netdev; 217 struct net_device *netdev = adapter->netdev;
223 struct sk_buff *skb; 218 union ixgbe_adv_tx_desc *tx_desc, *eop_desc;
224 unsigned int i; 219 struct ixgbe_tx_buffer *tx_buffer_info;
225 u32 head, oldhead; 220 unsigned int i, eop, count = 0;
226 unsigned int count = 0;
227 unsigned int total_bytes = 0, total_packets = 0; 221 unsigned int total_bytes = 0, total_packets = 0;
228 222
229 rmb();
230 head = GET_TX_HEAD_FROM_RING(tx_ring);
231 head = le32_to_cpu(head);
232 i = tx_ring->next_to_clean; 223 i = tx_ring->next_to_clean;
233 while (1) { 224 eop = tx_ring->tx_buffer_info[i].next_to_watch;
234 while (i != head) { 225 eop_desc = IXGBE_TX_DESC_ADV(*tx_ring, eop);
226
227 while ((eop_desc->wb.status & cpu_to_le32(IXGBE_TXD_STAT_DD)) &&
228 (count < tx_ring->count)) {
229 bool cleaned = false;
230 for ( ; !cleaned; count++) {
231 struct sk_buff *skb;
235 tx_desc = IXGBE_TX_DESC_ADV(*tx_ring, i); 232 tx_desc = IXGBE_TX_DESC_ADV(*tx_ring, i);
236 tx_buffer_info = &tx_ring->tx_buffer_info[i]; 233 tx_buffer_info = &tx_ring->tx_buffer_info[i];
234 cleaned = (i == eop);
237 skb = tx_buffer_info->skb; 235 skb = tx_buffer_info->skb;
238 236
239 if (skb) { 237 if (cleaned && skb) {
240 unsigned int segs, bytecount; 238 unsigned int segs, bytecount;
241 239
242 /* gso_segs is currently only valid for tcp */ 240 /* gso_segs is currently only valid for tcp */
@@ -251,23 +249,17 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_adapter *adapter,
251 ixgbe_unmap_and_free_tx_resource(adapter, 249 ixgbe_unmap_and_free_tx_resource(adapter,
252 tx_buffer_info); 250 tx_buffer_info);
253 251
252 tx_desc->wb.status = 0;
253
254 i++; 254 i++;
255 if (i == tx_ring->count) 255 if (i == tx_ring->count)
256 i = 0; 256 i = 0;
257
258 count++;
259 if (count == tx_ring->count)
260 goto done_cleaning;
261 } 257 }
262 oldhead = head; 258
263 rmb(); 259 eop = tx_ring->tx_buffer_info[i].next_to_watch;
264 head = GET_TX_HEAD_FROM_RING(tx_ring); 260 eop_desc = IXGBE_TX_DESC_ADV(*tx_ring, eop);
265 head = le32_to_cpu(head); 261 }
266 if (head == oldhead) 262
267 goto done_cleaning;
268 } /* while (1) */
269
270done_cleaning:
271 tx_ring->next_to_clean = i; 263 tx_ring->next_to_clean = i;
272 264
273#define TX_WAKE_THRESHOLD (DESC_NEEDED * 2) 265#define TX_WAKE_THRESHOLD (DESC_NEEDED * 2)
@@ -301,8 +293,8 @@ done_cleaning:
301 293
302 tx_ring->total_bytes += total_bytes; 294 tx_ring->total_bytes += total_bytes;
303 tx_ring->total_packets += total_packets; 295 tx_ring->total_packets += total_packets;
304 tx_ring->stats.bytes += total_bytes;
305 tx_ring->stats.packets += total_packets; 296 tx_ring->stats.packets += total_packets;
297 tx_ring->stats.bytes += total_bytes;
306 adapter->net_stats.tx_bytes += total_bytes; 298 adapter->net_stats.tx_bytes += total_bytes;
307 adapter->net_stats.tx_packets += total_packets; 299 adapter->net_stats.tx_packets += total_packets;
308 return (total_packets ? true : false); 300 return (total_packets ? true : false);
@@ -1484,7 +1476,7 @@ static void ixgbe_configure_msi_and_legacy(struct ixgbe_adapter *adapter)
1484 **/ 1476 **/
1485static void ixgbe_configure_tx(struct ixgbe_adapter *adapter) 1477static void ixgbe_configure_tx(struct ixgbe_adapter *adapter)
1486{ 1478{
1487 u64 tdba, tdwba; 1479 u64 tdba;
1488 struct ixgbe_hw *hw = &adapter->hw; 1480 struct ixgbe_hw *hw = &adapter->hw;
1489 u32 i, j, tdlen, txctrl; 1481 u32 i, j, tdlen, txctrl;
1490 1482
@@ -1497,11 +1489,6 @@ static void ixgbe_configure_tx(struct ixgbe_adapter *adapter)
1497 IXGBE_WRITE_REG(hw, IXGBE_TDBAL(j), 1489 IXGBE_WRITE_REG(hw, IXGBE_TDBAL(j),
1498 (tdba & DMA_32BIT_MASK)); 1490 (tdba & DMA_32BIT_MASK));
1499 IXGBE_WRITE_REG(hw, IXGBE_TDBAH(j), (tdba >> 32)); 1491 IXGBE_WRITE_REG(hw, IXGBE_TDBAH(j), (tdba >> 32));
1500 tdwba = ring->dma +
1501 (ring->count * sizeof(union ixgbe_adv_tx_desc));
1502 tdwba |= IXGBE_TDWBAL_HEAD_WB_ENABLE;
1503 IXGBE_WRITE_REG(hw, IXGBE_TDWBAL(j), tdwba & DMA_32BIT_MASK);
1504 IXGBE_WRITE_REG(hw, IXGBE_TDWBAH(j), (tdwba >> 32));
1505 IXGBE_WRITE_REG(hw, IXGBE_TDLEN(j), tdlen); 1492 IXGBE_WRITE_REG(hw, IXGBE_TDLEN(j), tdlen);
1506 IXGBE_WRITE_REG(hw, IXGBE_TDH(j), 0); 1493 IXGBE_WRITE_REG(hw, IXGBE_TDH(j), 0);
1507 IXGBE_WRITE_REG(hw, IXGBE_TDT(j), 0); 1494 IXGBE_WRITE_REG(hw, IXGBE_TDT(j), 0);
@@ -2880,8 +2867,7 @@ int ixgbe_setup_tx_resources(struct ixgbe_adapter *adapter,
2880 memset(tx_ring->tx_buffer_info, 0, size); 2867 memset(tx_ring->tx_buffer_info, 0, size);
2881 2868
2882 /* round up to nearest 4K */ 2869 /* round up to nearest 4K */
2883 tx_ring->size = tx_ring->count * sizeof(union ixgbe_adv_tx_desc) + 2870 tx_ring->size = tx_ring->count * sizeof(union ixgbe_adv_tx_desc);
2884 sizeof(u32);
2885 tx_ring->size = ALIGN(tx_ring->size, 4096); 2871 tx_ring->size = ALIGN(tx_ring->size, 4096);
2886 2872
2887 tx_ring->desc = pci_alloc_consistent(pdev, tx_ring->size, 2873 tx_ring->desc = pci_alloc_consistent(pdev, tx_ring->size,