From mboxrd@z Thu Jan 1 00:00:00 1970 From: Olivier Matz Subject: [RFC 9/9] net/e1000: add handler for tx queue descriptor count Date: Thu, 24 Nov 2016 10:54:21 +0100 Message-ID: <1479981261-19512-10-git-send-email-olivier.matz@6wind.com> References: <1479981261-19512-1-git-send-email-olivier.matz@6wind.com> Cc: thomas.monjalon@6wind.com, konstantin.ananyev@intel.com, wenzhuo.lu@intel.com, helin.zhang@intel.com To: dev@dpdk.org Return-path: Received: from proxy.6wind.com (host.76.145.23.62.rev.coltfrance.com [62.23.145.76]) by dpdk.org (Postfix) with ESMTP id F35CD5587 for ; Thu, 24 Nov 2016 10:59:38 +0100 (CET) In-Reply-To: <1479981261-19512-1-git-send-email-olivier.matz@6wind.com> List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Like for TX, use a binary search algorithm to get the number of used Tx descriptors. PR=52423 Signed-off-by: Olivier Matz Acked-by: Ivan Boule --- drivers/net/e1000/e1000_ethdev.h | 5 +++- drivers/net/e1000/em_ethdev.c | 1 + drivers/net/e1000/em_rxtx.c | 51 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 56 insertions(+), 1 deletion(-) diff --git a/drivers/net/e1000/e1000_ethdev.h b/drivers/net/e1000/e1000_ethdev.h index ad9ddaf..8945916 100644 --- a/drivers/net/e1000/e1000_ethdev.h +++ b/drivers/net/e1000/e1000_ethdev.h @@ -364,7 +364,10 @@ int eth_em_rx_queue_setup(struct rte_eth_dev *dev, uint16_t rx_queue_id, struct rte_mempool *mb_pool); uint32_t eth_em_rx_queue_count(struct rte_eth_dev *dev, - uint16_t rx_queue_id); + uint16_t rx_queue_id); + +uint32_t eth_em_tx_queue_count(struct rte_eth_dev *dev, + uint16_t tx_queue_id); int eth_em_rx_descriptor_done(void *rx_queue, uint16_t offset); diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c index 866a5cf..7fe5e3b 100644 --- a/drivers/net/e1000/em_ethdev.c +++ b/drivers/net/e1000/em_ethdev.c @@ -190,6 +190,7 @@ static const struct eth_dev_ops eth_em_ops = { .rx_queue_setup = eth_em_rx_queue_setup, .rx_queue_release = eth_em_rx_queue_release, .rx_queue_count = eth_em_rx_queue_count, + .tx_queue_count = eth_em_tx_queue_count, .rx_descriptor_done = eth_em_rx_descriptor_done, .tx_queue_setup = eth_em_tx_queue_setup, .tx_queue_release = eth_em_tx_queue_release, diff --git a/drivers/net/e1000/em_rxtx.c b/drivers/net/e1000/em_rxtx.c index a469fd7..8afcfda 100644 --- a/drivers/net/e1000/em_rxtx.c +++ b/drivers/net/e1000/em_rxtx.c @@ -1432,6 +1432,57 @@ eth_em_rx_queue_count(struct rte_eth_dev *dev, uint16_t rx_queue_id) return offset; } +uint32_t +eth_em_tx_queue_count(struct rte_eth_dev *dev, uint16_t tx_queue_id) +{ + volatile uint8_t *status; + struct em_tx_queue *txq; + int32_t offset, interval, idx, resolution; + + txq = dev->data->tx_queues[tx_queue_id]; + + /* check if ring empty */ + idx = txq->tx_tail - 1; + if (idx < 0) + idx += txq->nb_tx_desc; + status = &txq->tx_ring[idx].upper.fields.status; + if (*status & E1000_TXD_STAT_DD) + return 0; + + /* check if ring full */ + idx = txq->tx_tail + 1; + if (idx >= txq->nb_tx_desc) + idx -= txq->nb_tx_desc; + status = &txq->tx_ring[idx].upper.fields.status; + if (!(*status & E1000_TXD_STAT_DD)) + return txq->nb_tx_desc; + + /* decrease the precision if ring is large */ + if (txq->nb_tx_desc <= 256) + resolution = 4; + else + resolution = 16; + + /* use a binary search */ + offset = txq->nb_tx_desc >> 1; + interval = offset; + + do { + idx = txq->tx_tail + offset; + if (idx >= txq->nb_tx_desc) + idx -= txq->nb_tx_desc; + + interval >>= 1; + status = &txq->tx_ring[idx].upper.fields.status; + if (*status & E1000_TXD_STAT_DD) + offset += interval; + else + offset -= interval; + } while (interval >= resolution); + + return txq->nb_tx_desc - offset; +} + int eth_em_rx_descriptor_done(void *rx_queue, uint16_t offset) { -- 2.8.1