Reset transmit descriptors after they have been used */
| 561 | |
| 562 | /* Reset transmit descriptors after they have been used */ |
| 563 | static inline int |
| 564 | ixgbe_xmit_cleanup(struct ixgbe_tx_queue *txq) |
| 565 | { |
| 566 | struct ixgbe_tx_entry *sw_ring = txq->sw_ring; |
| 567 | volatile union ixgbe_adv_tx_desc *txr = txq->tx_ring; |
| 568 | uint16_t last_desc_cleaned = txq->last_desc_cleaned; |
| 569 | uint16_t nb_tx_desc = txq->nb_tx_desc; |
| 570 | uint16_t desc_to_clean_to; |
| 571 | uint16_t nb_tx_to_clean; |
| 572 | uint32_t status; |
| 573 | |
| 574 | /* Determine the last descriptor needing to be cleaned */ |
| 575 | desc_to_clean_to = (uint16_t)(last_desc_cleaned + txq->tx_rs_thresh); |
| 576 | if (desc_to_clean_to >= nb_tx_desc) |
| 577 | desc_to_clean_to = (uint16_t)(desc_to_clean_to - nb_tx_desc); |
| 578 | |
| 579 | /* Check to make sure the last descriptor to clean is done */ |
| 580 | desc_to_clean_to = sw_ring[desc_to_clean_to].last_id; |
| 581 | status = txr[desc_to_clean_to].wb.status; |
| 582 | if (!(status & rte_cpu_to_le_32(IXGBE_TXD_STAT_DD))) { |
| 583 | PMD_TX_LOG(DEBUG, |
| 584 | "TX descriptor %4u is not done" |
| 585 | "(port=%d queue=%d)", |
| 586 | desc_to_clean_to, |
| 587 | txq->port_id, txq->queue_id); |
| 588 | /* Failed to clean any descriptors, better luck next time */ |
| 589 | return -(1); |
| 590 | } |
| 591 | |
| 592 | /* Figure out how many descriptors will be cleaned */ |
| 593 | if (last_desc_cleaned > desc_to_clean_to) |
| 594 | nb_tx_to_clean = (uint16_t)((nb_tx_desc - last_desc_cleaned) + |
| 595 | desc_to_clean_to); |
| 596 | else |
| 597 | nb_tx_to_clean = (uint16_t)(desc_to_clean_to - |
| 598 | last_desc_cleaned); |
| 599 | |
| 600 | PMD_TX_LOG(DEBUG, |
| 601 | "Cleaning %4u TX descriptors: %4u to %4u " |
| 602 | "(port=%d queue=%d)", |
| 603 | nb_tx_to_clean, last_desc_cleaned, desc_to_clean_to, |
| 604 | txq->port_id, txq->queue_id); |
| 605 | |
| 606 | /* |
| 607 | * The last descriptor to clean is done, so that means all the |
| 608 | * descriptors from the last descriptor that was cleaned |
| 609 | * up to the last descriptor with the RS bit set |
| 610 | * are done. Only reset the threshold descriptor. |
| 611 | */ |
| 612 | txr[desc_to_clean_to].wb.status = 0; |
| 613 | |
| 614 | /* Update the txq to reflect the last descriptor that was cleaned */ |
| 615 | txq->last_desc_cleaned = desc_to_clean_to; |
| 616 | txq->nb_tx_free = (uint16_t)(txq->nb_tx_free + nb_tx_to_clean); |
| 617 | |
| 618 | /* No Error */ |
| 619 | return 0; |
| 620 | } |
no outgoing calls
no test coverage detected