From: Di ChenxuX <chenxux...@intel.com>

Add support to the i40e driver for the API rte_eth_tx_done_cleanup
 to force free consumed buffers on Tx ring.

Signed-off-by: Chenxu Di <chenxux...@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c    |  1 +
 drivers/net/i40e/i40e_ethdev_vf.c |  1 +
 drivers/net/i40e/i40e_rxtx.c      | 40 +++++++++++++++++++++++++++++++
 drivers/net/i40e/i40e_rxtx.h      |  1 +
 4 files changed, 43 insertions(+)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 5999c964b..fad47a942 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -522,6 +522,7 @@ static const struct eth_dev_ops i40e_eth_dev_ops = {
        .mac_addr_set                 = i40e_set_default_mac_addr,
        .mtu_set                      = i40e_dev_mtu_set,
        .tm_ops_get                   = i40e_tm_ops_get,
+       .tx_done_cleanup              = i40e_tx_done_cleanup,
 };
 
 /* store statistics names and its offset in stats structure */
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c 
b/drivers/net/i40e/i40e_ethdev_vf.c
index 5dba0928b..0ca5417d7 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -215,6 +215,7 @@ static const struct eth_dev_ops i40evf_eth_dev_ops = {
        .rss_hash_conf_get    = i40evf_dev_rss_hash_conf_get,
        .mtu_set              = i40evf_dev_mtu_set,
        .mac_addr_set         = i40evf_set_default_mac_addr,
+       .tx_done_cleanup      = i40e_tx_done_cleanup,
 };
 
 /*
diff --git a/drivers/net/i40e/i40e_rxtx.c b/drivers/net/i40e/i40e_rxtx.c
index 17dc8c78f..3280a3ff6 100644
--- a/drivers/net/i40e/i40e_rxtx.c
+++ b/drivers/net/i40e/i40e_rxtx.c
@@ -2455,6 +2455,46 @@ i40e_tx_queue_release_mbufs(struct i40e_tx_queue *txq)
        }
 }
 
+int i40e_tx_done_cleanup(void *txq, uint32_t free_cnt)
+{
+       struct i40e_tx_queue *q = (struct i40e_tx_queue *)txq;
+       struct i40e_tx_entry *sw_ring;
+       uint16_t tx_id;    /* Current segment being processed. */
+       uint16_t tx_cleaned;
+
+       int count = 0;
+
+       if (q == NULL)
+               return -ENODEV;
+
+       sw_ring = q->sw_ring;
+       tx_cleaned = q->last_desc_cleaned;
+       tx_id = sw_ring[q->last_desc_cleaned].next_id;
+       if ((q->tx_ring[tx_id].cmd_type_offset_bsz &
+                       rte_cpu_to_le_64(I40E_TXD_QW1_DTYPE_MASK)) !=
+                       rte_cpu_to_le_64(I40E_TX_DESC_DTYPE_DESC_DONE))
+               return 0;
+
+       do {
+               if (sw_ring[tx_id].mbuf == NULL)
+                       break;
+
+               rte_pktmbuf_free_seg(sw_ring[tx_id].mbuf);
+               sw_ring[tx_id].mbuf = NULL;
+               sw_ring[tx_id].last_id = tx_id;
+
+               /* Move to next segemnt. */
+               tx_cleaned = tx_id;
+               tx_id = sw_ring[tx_id].next_id;
+               count++;
+       } while (count != (int)free_cnt);
+
+       q->nb_tx_free += (uint16_t)count;
+       q->last_desc_cleaned = tx_cleaned;
+
+       return count;
+}
+
 void
 i40e_reset_tx_queue(struct i40e_tx_queue *txq)
 {
diff --git a/drivers/net/i40e/i40e_rxtx.h b/drivers/net/i40e/i40e_rxtx.h
index 2106bb355..8f11f011a 100644
--- a/drivers/net/i40e/i40e_rxtx.h
+++ b/drivers/net/i40e/i40e_rxtx.h
@@ -212,6 +212,7 @@ void i40e_dev_free_queues(struct rte_eth_dev *dev);
 void i40e_reset_rx_queue(struct i40e_rx_queue *rxq);
 void i40e_reset_tx_queue(struct i40e_tx_queue *txq);
 void i40e_tx_queue_release_mbufs(struct i40e_tx_queue *txq);
+int i40e_tx_done_cleanup(void *txq, uint32_t free_cnt);
 int i40e_alloc_rx_queue_mbufs(struct i40e_rx_queue *rxq);
 void i40e_rx_queue_release_mbufs(struct i40e_rx_queue *rxq);
 
-- 
2.17.1

Reply via email to