Skip to content

Commit

Permalink
net/bnxt: fix Tx descriptor status implementation
Browse files Browse the repository at this point in the history
[ upstream commit ce5c57a ]

With Tx completion batching, a single transmit completion
can correspond to one or more transmit descriptors, adjust
implementation to account for this.

RTE_ETH_TX_DESC_DONE should be returned for descriptors that
are available for use instead of RTE_ETH_TX_DESC_UNAVAIL.

Fixes: 5735eb2 ("net/bnxt: support Tx batching")
Fixes: 478ed3b ("net/bnxt: support Tx descriptor status")

Signed-off-by: Lance Richardson <lance.richardson@broadcom.com>
Reviewed-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
  • Loading branch information
Lance Richardson authored and bluca committed Jul 12, 2021
1 parent 233e613 commit 2dfab9a
Showing 1 changed file with 31 additions and 23 deletions.
54 changes: 31 additions & 23 deletions drivers/net/bnxt/bnxt_ethdev.c
Expand Up @@ -3213,41 +3213,49 @@ static int
bnxt_tx_descriptor_status_op(void *tx_queue, uint16_t offset)
{
struct bnxt_tx_queue *txq = (struct bnxt_tx_queue *)tx_queue;
struct bnxt_tx_ring_info *txr;
struct bnxt_cp_ring_info *cpr;
struct bnxt_sw_tx_bd *tx_buf;
struct tx_pkt_cmpl *txcmp;
uint32_t cons, cp_cons;
struct bnxt_cp_ring_info *cpr = txq->cp_ring;
uint32_t ring_mask, raw_cons, nb_tx_pkts = 0;
struct bnxt_ring *cp_ring_struct;
struct cmpl_base *cp_desc_ring;
int rc;

if (!txq)
return -EINVAL;

rc = is_bnxt_in_error(txq->bp);
if (rc)
return rc;

cpr = txq->cp_ring;
txr = txq->tx_ring;

if (offset >= txq->nb_tx_desc)
return -EINVAL;

cons = RING_CMP(cpr->cp_ring_struct, offset);
txcmp = (struct tx_pkt_cmpl *)&cpr->cp_desc_ring[cons];
cp_cons = cpr->cp_raw_cons;
/* Return "desc done" if descriptor is available for use. */
if (bnxt_tx_bds_in_hw(txq) <= offset)
return RTE_ETH_TX_DESC_DONE;

if (cons > cp_cons) {
if (CMPL_VALID(txcmp, cpr->valid))
return RTE_ETH_TX_DESC_UNAVAIL;
} else {
if (CMPL_VALID(txcmp, !cpr->valid))
return RTE_ETH_TX_DESC_UNAVAIL;
raw_cons = cpr->cp_raw_cons;
cp_desc_ring = cpr->cp_desc_ring;
cp_ring_struct = cpr->cp_ring_struct;
ring_mask = cpr->cp_ring_struct->ring_mask;

/* Check to see if hw has posted a completion for the descriptor. */
while (1) {
struct tx_cmpl *txcmp;
uint32_t cons;

cons = RING_CMPL(ring_mask, raw_cons);
txcmp = (struct tx_cmpl *)&cp_desc_ring[cons];

if (!CMP_VALID(txcmp, raw_cons, cp_ring_struct))
break;

if (CMP_TYPE(txcmp) == TX_CMPL_TYPE_TX_L2)
nb_tx_pkts += rte_le_to_cpu_32(txcmp->opaque);

if (nb_tx_pkts > offset)
return RTE_ETH_TX_DESC_DONE;

raw_cons = NEXT_RAW_CMP(raw_cons);
}
tx_buf = &txr->tx_buf_ring[cons];
if (tx_buf->mbuf == NULL)
return RTE_ETH_TX_DESC_DONE;

/* Descriptor is pending transmit, not yet completed by hardware. */
return RTE_ETH_TX_DESC_FULL;
}

Expand Down

0 comments on commit 2dfab9a

Please sign in to comment.