The write-back pointer was not reset when the Tx queue was reset. This
leads to the wrong Tx desc free logic. Move the resetting of pointer into
txq->ops->reset(txq).

Fixes: 8ada71d0bb7f ("net/txgbe: add Tx head write-back mode for Amber-Lite")
Cc: [email protected]

Signed-off-by: Zaiyu Wang <[email protected]>
---
 drivers/net/txgbe/txgbe_rxtx.c            | 45 +++++++++++++----------
 drivers/net/txgbe/txgbe_rxtx.h            |  1 +
 drivers/net/txgbe/txgbe_rxtx_vec_common.h |  7 ++++
 3 files changed, 33 insertions(+), 20 deletions(-)

diff --git a/drivers/net/txgbe/txgbe_rxtx.c b/drivers/net/txgbe/txgbe_rxtx.c
index 851cd122d8..ef53a868a6 100644
--- a/drivers/net/txgbe/txgbe_rxtx.c
+++ b/drivers/net/txgbe/txgbe_rxtx.c
@@ -2320,6 +2320,12 @@ txgbe_reset_tx_queue(struct txgbe_tx_queue *txq)
        txq->tx_next_dd = (uint16_t)(txq->tx_free_thresh - 1);
        txq->tx_tail = 0;
 
+       /* Zero out headwb_mem memory */
+       if (txq->headwb_mem) {
+               for (i = 0; i < txq->headwb_size; i++)
+                       txq->headwb_mem[i] = 0;
+       }
+
        /*
         * Always allow 1 descriptor to be un-allocated to avoid
         * a H/W race condition
@@ -2419,7 +2425,7 @@ txgbe_get_tx_port_offloads(struct rte_eth_dev *dev)
        return tx_offload_capa;
 }
 
-static int
+static void
 txgbe_setup_headwb_resources(struct rte_eth_dev *dev,
                                        void *tx_queue,
                                        unsigned int socket_id)
@@ -2427,33 +2433,33 @@ txgbe_setup_headwb_resources(struct rte_eth_dev *dev,
        struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
        const struct rte_memzone *headwb;
        struct txgbe_tx_queue *txq = tx_queue;
-       u8 i, headwb_size = 0;
+       u8 headwb_size = 0;
 
-       if (hw->mac.type != txgbe_mac_aml && hw->mac.type != txgbe_mac_aml40) {
-               txq->headwb_mem = NULL;
-               return 0;
-       }
+       if (hw->mac.type != txgbe_mac_aml && hw->mac.type != txgbe_mac_aml40)
+               goto out;
+
+       if (!hw->devarg.tx_headwb)
+               goto out;
 
-       headwb_size = hw->devarg.tx_headwb_size;
+       headwb_size = txq->headwb_size;
        headwb = rte_eth_dma_zone_reserve(dev, "tx_headwb_mem", txq->queue_id,
                        sizeof(u32) * headwb_size,
                        TXGBE_ALIGN, socket_id);
 
        if (headwb == NULL) {
-               DEBUGOUT("Fail to setup headwb resources: no mem");
-               txgbe_tx_queue_release(txq);
-               return -ENOMEM;
+               PMD_DRV_LOG(INFO,
+                           "Failed to allocate headwb memory for Tx queue %u, 
change to SP mode",
+                           txq->queue_id);
+               goto out;
        }
 
        txq->headwb = headwb;
        txq->headwb_dma = TMZ_PADDR(headwb);
        txq->headwb_mem = (uint32_t *)TMZ_VADDR(headwb);
+       return;
 
-       /* Zero out headwb_mem memory */
-       for (i = 0; i < headwb_size; i++)
-               txq->headwb_mem[i] = 0;
-
-       return 0;
+out:
+       txq->headwb_mem = NULL;
 }
 
 int __rte_cold
@@ -2549,6 +2555,7 @@ txgbe_dev_tx_queue_setup(struct rte_eth_dev *dev,
        txq->offloads = offloads;
        txq->ops = &def_txq_ops;
        txq->tx_deferred_start = tx_conf->tx_deferred_start;
+       txq->headwb_size = hw->devarg.tx_headwb_size;
 #ifdef RTE_LIB_SECURITY
        txq->using_ipsec = !!(dev->data->dev_conf.txmode.offloads &
                        RTE_ETH_TX_OFFLOAD_SECURITY);
@@ -2584,8 +2591,7 @@ txgbe_dev_tx_queue_setup(struct rte_eth_dev *dev,
        /* set up scalar TX function as appropriate */
        txgbe_set_tx_function(dev, txq);
 
-       if (hw->devarg.tx_headwb)
-               err = txgbe_setup_headwb_resources(dev, txq, socket_id);
+       txgbe_setup_headwb_resources(dev, txq, socket_id);
 
        txq->ops->reset(txq);
        txq->desc_error = 0;
@@ -4762,15 +4768,14 @@ txgbe_dev_tx_init(struct rte_eth_dev *dev)
                wr32(hw, TXGBE_TXRP(txq->reg_idx), 0);
                wr32(hw, TXGBE_TXWP(txq->reg_idx), 0);
 
-               if ((hw->mac.type == txgbe_mac_aml || hw->mac.type == 
txgbe_mac_aml40) &&
-                    hw->devarg.tx_headwb) {
+               if (txq->headwb_mem) {
                        uint32_t txdctl;
 
                        wr32(hw, TXGBE_PX_TR_HEAD_ADDRL(txq->reg_idx),
                                (uint32_t)(txq->headwb_dma & BIT_MASK32));
                        wr32(hw, TXGBE_PX_TR_HEAD_ADDRH(txq->reg_idx),
                                (uint32_t)(txq->headwb_dma >> 32));
-                       if (hw->devarg.tx_headwb_size == 16)
+                       if (txq->headwb_size == 16)
                                txdctl = TXGBE_PX_TR_CFG_HEAD_WB |
                                         TXGBE_PX_TR_CFG_HEAD_WB_64BYTE;
                        else
diff --git a/drivers/net/txgbe/txgbe_rxtx.h b/drivers/net/txgbe/txgbe_rxtx.h
index 02e2617cce..237bb64697 100644
--- a/drivers/net/txgbe/txgbe_rxtx.h
+++ b/drivers/net/txgbe/txgbe_rxtx.h
@@ -416,6 +416,7 @@ struct txgbe_tx_queue {
        uint64_t            desc_error;
        bool                resetting;
        const struct rte_memzone *headwb;
+       uint16_t             headwb_size;
        uint64_t             headwb_dma;
        volatile uint32_t    *headwb_mem;
 };
diff --git a/drivers/net/txgbe/txgbe_rxtx_vec_common.h 
b/drivers/net/txgbe/txgbe_rxtx_vec_common.h
index edf3586b77..594886c5b1 100644
--- a/drivers/net/txgbe/txgbe_rxtx_vec_common.h
+++ b/drivers/net/txgbe/txgbe_rxtx_vec_common.h
@@ -255,6 +255,13 @@ _txgbe_reset_tx_queue_vec(struct txgbe_tx_queue *txq)
        txq->tx_next_dd = (uint16_t)(txq->tx_free_thresh - 1);
 
        txq->tx_tail = 0;
+
+       /* Zero out headwb_mem memory */
+       if (txq->headwb_mem) {
+               for (i = 0; i < txq->headwb_size; i++)
+                       txq->headwb_mem[i] = 0;
+       }
+
        /*
         * Always allow 1 descriptor to be un-allocated to avoid
         * a H/W race condition
-- 
2.21.0.windows.1

Reply via email to