aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/intel/i40e/i40e_txrx.c
diff options
context:
space:
mode:
authorAlexander Duyck <alexander.h.duyck@intel.com>2013-09-28 02:00:27 -0400
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2013-10-10 00:58:04 -0400
commita5e9c5726424b05a3643450d45c134cea103181e (patch)
tree33b514501c51d193e3a85b82addfec2feaaa2bb7 /drivers/net/ethernet/intel/i40e/i40e_txrx.c
parentfc4ac67bc98f1d54ec0ef8bcddf54892ad78e1f9 (diff)
i40e: clean up Tx fast path
Sync the fast path for i40e_tx_map and i40e_clean_tx_irq so that they are similar to igb and ixgbe. - Only update the Tx descriptor ring in tx_map - Make skb mapping always on the first buffer in the chain - Drop the use of MAPPED_AS_PAGE Tx flag - Only store flags on the first buffer_info structure Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com> Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com> Tested-by: Kavindya Deegala <kavindya.s.deegala@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/ethernet/intel/i40e/i40e_txrx.c')
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_txrx.c220
1 files changed, 122 insertions, 98 deletions
diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c
index e8db4dca6e85..e96de7567856 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c
@@ -189,27 +189,30 @@ static void i40e_fd_handle_status(struct i40e_ring *rx_ring, u32 qw, u8 prog_id)
189} 189}
190 190
191/** 191/**
192 * i40e_unmap_tx_resource - Release a Tx buffer 192 * i40e_unmap_and_free_tx_resource - Release a Tx buffer
193 * @ring: the ring that owns the buffer 193 * @ring: the ring that owns the buffer
194 * @tx_buffer: the buffer to free 194 * @tx_buffer: the buffer to free
195 **/ 195 **/
196static inline void i40e_unmap_tx_resource(struct i40e_ring *ring, 196static void i40e_unmap_and_free_tx_resource(struct i40e_ring *ring,
197 struct i40e_tx_buffer *tx_buffer) 197 struct i40e_tx_buffer *tx_buffer)
198{ 198{
199 if (dma_unmap_len(tx_buffer, len)) { 199 if (tx_buffer->skb) {
200 if (tx_buffer->tx_flags & I40E_TX_FLAGS_MAPPED_AS_PAGE) 200 dev_kfree_skb_any(tx_buffer->skb);
201 dma_unmap_page(ring->dev, 201 if (dma_unmap_len(tx_buffer, len))
202 dma_unmap_addr(tx_buffer, dma),
203 dma_unmap_len(tx_buffer, len),
204 DMA_TO_DEVICE);
205 else
206 dma_unmap_single(ring->dev, 202 dma_unmap_single(ring->dev,
207 dma_unmap_addr(tx_buffer, dma), 203 dma_unmap_addr(tx_buffer, dma),
208 dma_unmap_len(tx_buffer, len), 204 dma_unmap_len(tx_buffer, len),
209 DMA_TO_DEVICE); 205 DMA_TO_DEVICE);
206 } else if (dma_unmap_len(tx_buffer, len)) {
207 dma_unmap_page(ring->dev,
208 dma_unmap_addr(tx_buffer, dma),
209 dma_unmap_len(tx_buffer, len),
210 DMA_TO_DEVICE);
210 } 211 }
211 tx_buffer->time_stamp = 0; 212 tx_buffer->next_to_watch = NULL;
213 tx_buffer->skb = NULL;
212 dma_unmap_len_set(tx_buffer, len, 0); 214 dma_unmap_len_set(tx_buffer, len, 0);
215 /* tx_buffer must be completely set up in the transmit path */
213} 216}
214 217
215/** 218/**
@@ -218,7 +221,6 @@ static inline void i40e_unmap_tx_resource(struct i40e_ring *ring,
218 **/ 221 **/
219void i40e_clean_tx_ring(struct i40e_ring *tx_ring) 222void i40e_clean_tx_ring(struct i40e_ring *tx_ring)
220{ 223{
221 struct i40e_tx_buffer *tx_buffer;
222 unsigned long bi_size; 224 unsigned long bi_size;
223 u16 i; 225 u16 i;
224 226
@@ -227,13 +229,8 @@ void i40e_clean_tx_ring(struct i40e_ring *tx_ring)
227 return; 229 return;
228 230
229 /* Free all the Tx ring sk_buffs */ 231 /* Free all the Tx ring sk_buffs */
230 for (i = 0; i < tx_ring->count; i++) { 232 for (i = 0; i < tx_ring->count; i++)
231 tx_buffer = &tx_ring->tx_bi[i]; 233 i40e_unmap_and_free_tx_resource(tx_ring, &tx_ring->tx_bi[i]);
232 i40e_unmap_tx_resource(tx_ring, tx_buffer);
233 if (tx_buffer->skb)
234 dev_kfree_skb_any(tx_buffer->skb);
235 tx_buffer->skb = NULL;
236 }
237 234
238 bi_size = sizeof(struct i40e_tx_buffer) * tx_ring->count; 235 bi_size = sizeof(struct i40e_tx_buffer) * tx_ring->count;
239 memset(tx_ring->tx_bi, 0, bi_size); 236 memset(tx_ring->tx_bi, 0, bi_size);
@@ -332,16 +329,18 @@ static bool i40e_clean_tx_irq(struct i40e_ring *tx_ring, int budget)
332 329
333 tx_buf = &tx_ring->tx_bi[i]; 330 tx_buf = &tx_ring->tx_bi[i];
334 tx_desc = I40E_TX_DESC(tx_ring, i); 331 tx_desc = I40E_TX_DESC(tx_ring, i);
332 i -= tx_ring->count;
335 333
336 for (; budget; budget--) { 334 do {
337 struct i40e_tx_desc *eop_desc; 335 struct i40e_tx_desc *eop_desc = tx_buf->next_to_watch;
338
339 eop_desc = tx_buf->next_to_watch;
340 336
341 /* if next_to_watch is not set then there is no work pending */ 337 /* if next_to_watch is not set then there is no work pending */
342 if (!eop_desc) 338 if (!eop_desc)
343 break; 339 break;
344 340
341 /* prevent any other reads prior to eop_desc */
342 read_barrier_depends();
343
345 /* if the descriptor isn't done, no work yet to do */ 344 /* if the descriptor isn't done, no work yet to do */
346 if (!(eop_desc->cmd_type_offset_bsz & 345 if (!(eop_desc->cmd_type_offset_bsz &
347 cpu_to_le64(I40E_TX_DESC_DTYPE_DESC_DONE))) 346 cpu_to_le64(I40E_TX_DESC_DTYPE_DESC_DONE)))
@@ -349,44 +348,67 @@ static bool i40e_clean_tx_irq(struct i40e_ring *tx_ring, int budget)
349 348
350 /* clear next_to_watch to prevent false hangs */ 349 /* clear next_to_watch to prevent false hangs */
351 tx_buf->next_to_watch = NULL; 350 tx_buf->next_to_watch = NULL;
352 tx_buf->time_stamp = 0;
353 351
354 /* set memory barrier before eop_desc is verified */ 352 /* update the statistics for this packet */
355 rmb(); 353 total_bytes += tx_buf->bytecount;
354 total_packets += tx_buf->gso_segs;
356 355
357 do { 356 /* free the skb */
358 i40e_unmap_tx_resource(tx_ring, tx_buf); 357 dev_kfree_skb_any(tx_buf->skb);
359 358
360 /* clear dtype status */ 359 /* unmap skb header data */
361 tx_desc->cmd_type_offset_bsz &= 360 dma_unmap_single(tx_ring->dev,
362 ~cpu_to_le64(I40E_TXD_QW1_DTYPE_MASK); 361 dma_unmap_addr(tx_buf, dma),
362 dma_unmap_len(tx_buf, len),
363 DMA_TO_DEVICE);
363 364
364 if (likely(tx_desc == eop_desc)) { 365 /* clear tx_buffer data */
365 eop_desc = NULL; 366 tx_buf->skb = NULL;
367 dma_unmap_len_set(tx_buf, len, 0);
366 368
367 dev_kfree_skb_any(tx_buf->skb); 369 /* unmap remaining buffers */
368 tx_buf->skb = NULL; 370 while (tx_desc != eop_desc) {
369
370 total_bytes += tx_buf->bytecount;
371 total_packets += tx_buf->gso_segs;
372 }
373 371
374 tx_buf++; 372 tx_buf++;
375 tx_desc++; 373 tx_desc++;
376 i++; 374 i++;
377 if (unlikely(i == tx_ring->count)) { 375 if (unlikely(!i)) {
378 i = 0; 376 i -= tx_ring->count;
379 tx_buf = tx_ring->tx_bi; 377 tx_buf = tx_ring->tx_bi;
380 tx_desc = I40E_TX_DESC(tx_ring, 0); 378 tx_desc = I40E_TX_DESC(tx_ring, 0);
381 } 379 }
382 } while (eop_desc);
383 }
384 380
381 /* unmap any remaining paged data */
382 if (dma_unmap_len(tx_buf, len)) {
383 dma_unmap_page(tx_ring->dev,
384 dma_unmap_addr(tx_buf, dma),
385 dma_unmap_len(tx_buf, len),
386 DMA_TO_DEVICE);
387 dma_unmap_len_set(tx_buf, len, 0);
388 }
389 }
390
391 /* move us one more past the eop_desc for start of next pkt */
392 tx_buf++;
393 tx_desc++;
394 i++;
395 if (unlikely(!i)) {
396 i -= tx_ring->count;
397 tx_buf = tx_ring->tx_bi;
398 tx_desc = I40E_TX_DESC(tx_ring, 0);
399 }
400
401 /* update budget accounting */
402 budget--;
403 } while (likely(budget));
404
405 i += tx_ring->count;
385 tx_ring->next_to_clean = i; 406 tx_ring->next_to_clean = i;
386 tx_ring->tx_stats.bytes += total_bytes; 407 tx_ring->tx_stats.bytes += total_bytes;
387 tx_ring->tx_stats.packets += total_packets; 408 tx_ring->tx_stats.packets += total_packets;
388 tx_ring->q_vector->tx.total_bytes += total_bytes; 409 tx_ring->q_vector->tx.total_bytes += total_bytes;
389 tx_ring->q_vector->tx.total_packets += total_packets; 410 tx_ring->q_vector->tx.total_packets += total_packets;
411
390 if (check_for_tx_hang(tx_ring) && i40e_check_tx_hang(tx_ring)) { 412 if (check_for_tx_hang(tx_ring) && i40e_check_tx_hang(tx_ring)) {
391 /* schedule immediate reset if we believe we hung */ 413 /* schedule immediate reset if we believe we hung */
392 dev_info(tx_ring->dev, "Detected Tx Unit Hang\n" 414 dev_info(tx_ring->dev, "Detected Tx Unit Hang\n"
@@ -1515,68 +1537,71 @@ static void i40e_tx_map(struct i40e_ring *tx_ring, struct sk_buff *skb,
1515 struct i40e_tx_buffer *first, u32 tx_flags, 1537 struct i40e_tx_buffer *first, u32 tx_flags,
1516 const u8 hdr_len, u32 td_cmd, u32 td_offset) 1538 const u8 hdr_len, u32 td_cmd, u32 td_offset)
1517{ 1539{
1518 struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[0];
1519 unsigned int data_len = skb->data_len; 1540 unsigned int data_len = skb->data_len;
1520 unsigned int size = skb_headlen(skb); 1541 unsigned int size = skb_headlen(skb);
1521 struct device *dev = tx_ring->dev; 1542 struct skb_frag_struct *frag;
1522 u32 paylen = skb->len - hdr_len;
1523 u16 i = tx_ring->next_to_use;
1524 struct i40e_tx_buffer *tx_bi; 1543 struct i40e_tx_buffer *tx_bi;
1525 struct i40e_tx_desc *tx_desc; 1544 struct i40e_tx_desc *tx_desc;
1526 u32 buf_offset = 0; 1545 u16 i = tx_ring->next_to_use;
1527 u32 td_tag = 0; 1546 u32 td_tag = 0;
1528 dma_addr_t dma; 1547 dma_addr_t dma;
1529 u16 gso_segs; 1548 u16 gso_segs;
1530 1549
1531 dma = dma_map_single(dev, skb->data, size, DMA_TO_DEVICE);
1532 if (dma_mapping_error(dev, dma))
1533 goto dma_error;
1534
1535 if (tx_flags & I40E_TX_FLAGS_HW_VLAN) { 1550 if (tx_flags & I40E_TX_FLAGS_HW_VLAN) {
1536 td_cmd |= I40E_TX_DESC_CMD_IL2TAG1; 1551 td_cmd |= I40E_TX_DESC_CMD_IL2TAG1;
1537 td_tag = (tx_flags & I40E_TX_FLAGS_VLAN_MASK) >> 1552 td_tag = (tx_flags & I40E_TX_FLAGS_VLAN_MASK) >>
1538 I40E_TX_FLAGS_VLAN_SHIFT; 1553 I40E_TX_FLAGS_VLAN_SHIFT;
1539 } 1554 }
1540 1555
1556 if (tx_flags & (I40E_TX_FLAGS_TSO | I40E_TX_FLAGS_FSO))
1557 gso_segs = skb_shinfo(skb)->gso_segs;
1558 else
1559 gso_segs = 1;
1560
1561 /* multiply data chunks by size of headers */
1562 first->bytecount = skb->len - hdr_len + (gso_segs * hdr_len);
1563 first->gso_segs = gso_segs;
1564 first->skb = skb;
1565 first->tx_flags = tx_flags;
1566
1567 dma = dma_map_single(tx_ring->dev, skb->data, size, DMA_TO_DEVICE);
1568
1541 tx_desc = I40E_TX_DESC(tx_ring, i); 1569 tx_desc = I40E_TX_DESC(tx_ring, i);
1542 for (;;) { 1570 tx_bi = first;
1543 while (size > I40E_MAX_DATA_PER_TXD) { 1571
1544 tx_desc->buffer_addr = cpu_to_le64(dma + buf_offset); 1572 for (frag = &skb_shinfo(skb)->frags[0];; frag++) {
1573 if (dma_mapping_error(tx_ring->dev, dma))
1574 goto dma_error;
1575
1576 /* record length, and DMA address */
1577 dma_unmap_len_set(tx_bi, len, size);
1578 dma_unmap_addr_set(tx_bi, dma, dma);
1579
1580 tx_desc->buffer_addr = cpu_to_le64(dma);
1581
1582 while (unlikely(size > I40E_MAX_DATA_PER_TXD)) {
1545 tx_desc->cmd_type_offset_bsz = 1583 tx_desc->cmd_type_offset_bsz =
1546 build_ctob(td_cmd, td_offset, 1584 build_ctob(td_cmd, td_offset,
1547 I40E_MAX_DATA_PER_TXD, td_tag); 1585 I40E_MAX_DATA_PER_TXD, td_tag);
1548 1586
1549 buf_offset += I40E_MAX_DATA_PER_TXD;
1550 size -= I40E_MAX_DATA_PER_TXD;
1551
1552 tx_desc++; 1587 tx_desc++;
1553 i++; 1588 i++;
1554 if (i == tx_ring->count) { 1589 if (i == tx_ring->count) {
1555 tx_desc = I40E_TX_DESC(tx_ring, 0); 1590 tx_desc = I40E_TX_DESC(tx_ring, 0);
1556 i = 0; 1591 i = 0;
1557 } 1592 }
1558 }
1559 1593
1560 tx_bi = &tx_ring->tx_bi[i]; 1594 dma += I40E_MAX_DATA_PER_TXD;
1561 dma_unmap_len_set(tx_bi, len, buf_offset + size); 1595 size -= I40E_MAX_DATA_PER_TXD;
1562 dma_unmap_addr_set(tx_bi, dma, dma);
1563 tx_bi->tx_flags = tx_flags;
1564 1596
1565 tx_desc->buffer_addr = cpu_to_le64(dma + buf_offset); 1597 tx_desc->buffer_addr = cpu_to_le64(dma);
1566 tx_desc->cmd_type_offset_bsz = build_ctob(td_cmd, td_offset, 1598 }
1567 size, td_tag);
1568 1599
1569 if (likely(!data_len)) 1600 if (likely(!data_len))
1570 break; 1601 break;
1571 1602
1572 size = skb_frag_size(frag); 1603 tx_desc->cmd_type_offset_bsz = build_ctob(td_cmd, td_offset,
1573 data_len -= size; 1604 size, td_tag);
1574 buf_offset = 0;
1575 tx_flags |= I40E_TX_FLAGS_MAPPED_AS_PAGE;
1576
1577 dma = skb_frag_dma_map(dev, frag, 0, size, DMA_TO_DEVICE);
1578 if (dma_mapping_error(dev, dma))
1579 goto dma_error;
1580 1605
1581 tx_desc++; 1606 tx_desc++;
1582 i++; 1607 i++;
@@ -1585,31 +1610,21 @@ static void i40e_tx_map(struct i40e_ring *tx_ring, struct sk_buff *skb,
1585 i = 0; 1610 i = 0;
1586 } 1611 }
1587 1612
1588 frag++; 1613 size = skb_frag_size(frag);
1589 } 1614 data_len -= size;
1590
1591 tx_desc->cmd_type_offset_bsz |=
1592 cpu_to_le64((u64)I40E_TXD_CMD << I40E_TXD_QW1_CMD_SHIFT);
1593
1594 i++;
1595 if (i == tx_ring->count)
1596 i = 0;
1597 1615
1598 tx_ring->next_to_use = i; 1616 dma = skb_frag_dma_map(tx_ring->dev, frag, 0, size,
1617 DMA_TO_DEVICE);
1599 1618
1600 if (tx_flags & (I40E_TX_FLAGS_TSO | I40E_TX_FLAGS_FSO)) 1619 tx_bi = &tx_ring->tx_bi[i];
1601 gso_segs = skb_shinfo(skb)->gso_segs; 1620 }
1602 else
1603 gso_segs = 1;
1604 1621
1605 /* multiply data chunks by size of headers */ 1622 tx_desc->cmd_type_offset_bsz =
1606 tx_bi->bytecount = paylen + (gso_segs * hdr_len); 1623 build_ctob(td_cmd, td_offset, size, td_tag) |
1607 tx_bi->gso_segs = gso_segs; 1624 cpu_to_le64((u64)I40E_TXD_CMD << I40E_TXD_QW1_CMD_SHIFT);
1608 tx_bi->skb = skb;
1609 1625
1610 /* set the timestamp and next to watch values */ 1626 /* set the timestamp */
1611 first->time_stamp = jiffies; 1627 first->time_stamp = jiffies;
1612 first->next_to_watch = tx_desc;
1613 1628
1614 /* Force memory writes to complete before letting h/w 1629 /* Force memory writes to complete before letting h/w
1615 * know there are new descriptors to fetch. (Only 1630 * know there are new descriptors to fetch. (Only
@@ -1618,16 +1633,27 @@ static void i40e_tx_map(struct i40e_ring *tx_ring, struct sk_buff *skb,
1618 */ 1633 */
1619 wmb(); 1634 wmb();
1620 1635
1636 /* set next_to_watch value indicating a packet is present */
1637 first->next_to_watch = tx_desc;
1638
1639 i++;
1640 if (i == tx_ring->count)
1641 i = 0;
1642
1643 tx_ring->next_to_use = i;
1644
1645 /* notify HW of packet */
1621 writel(i, tx_ring->tail); 1646 writel(i, tx_ring->tail);
1647
1622 return; 1648 return;
1623 1649
1624dma_error: 1650dma_error:
1625 dev_info(dev, "TX DMA map failed\n"); 1651 dev_info(tx_ring->dev, "TX DMA map failed\n");
1626 1652
1627 /* clear dma mappings for failed tx_bi map */ 1653 /* clear dma mappings for failed tx_bi map */
1628 for (;;) { 1654 for (;;) {
1629 tx_bi = &tx_ring->tx_bi[i]; 1655 tx_bi = &tx_ring->tx_bi[i];
1630 i40e_unmap_tx_resource(tx_ring, tx_bi); 1656 i40e_unmap_and_free_tx_resource(tx_ring, tx_bi);
1631 if (tx_bi == first) 1657 if (tx_bi == first)
1632 break; 1658 break;
1633 if (i == 0) 1659 if (i == 0)
@@ -1635,8 +1661,6 @@ dma_error:
1635 i--; 1661 i--;
1636 } 1662 }
1637 1663
1638 dev_kfree_skb_any(skb);
1639
1640 tx_ring->next_to_use = i; 1664 tx_ring->next_to_use = i;
1641} 1665}
1642 1666