X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fenetc%2Fenetc_rxtx.c;h=262ed8a0fdbcd823fca4a18e9348c271dd14a743;hb=11a6dc423bc626e28343b1df7a1570a64ca8ebc8;hp=81b0ef3b148cfac60a116c1931b265f2134d227c;hpb=e091c6915e3ed468d4f5299e409afa4a89436735;p=dpdk.git diff --git a/drivers/net/enetc/enetc_rxtx.c b/drivers/net/enetc/enetc_rxtx.c index 81b0ef3b14..262ed8a0fd 100644 --- a/drivers/net/enetc/enetc_rxtx.c +++ b/drivers/net/enetc/enetc_rxtx.c @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: BSD-3-Clause - * Copyright 2018-2019 NXP + * Copyright 2018-2020 NXP */ #include @@ -14,19 +14,32 @@ #include "enetc.h" #include "enetc_logs.h" -#define ENETC_RXBD_BUNDLE 8 /* Number of BDs to update at once */ - static int enetc_clean_tx_ring(struct enetc_bdr *tx_ring) { int tx_frm_cnt = 0; struct enetc_swbd *tx_swbd; - int i; + int i, hwci; + + /* we don't need barriers here, we just want a relatively current value + * from HW. + */ + hwci = (int)(rte_read32_relaxed(tx_ring->tcisr) & + ENETC_TBCISR_IDX_MASK); i = tx_ring->next_to_clean; tx_swbd = &tx_ring->q_swbd[i]; - while ((int)(enetc_rd_reg(tx_ring->tcisr) & - ENETC_TBCISR_IDX_MASK) != i) { + + /* we're only reading the CI index once here, which means HW may update + * it while we're doing clean-up. We could read the register in a loop + * but for now I assume it's OK to leave a few Tx frames for next call. + * The issue with reading the register in a loop is that we're stalling + * here trying to catch up with HW which keeps sending traffic as long + * as it has traffic to send, so in effect we could be waiting here for + * the Tx ring to be drained by HW, instead of us doing Rx in that + * meantime. + */ + while (i != hwci) { rte_pktmbuf_free(tx_swbd->buffer_addr); tx_swbd->buffer_addr = NULL; tx_swbd++; @@ -61,7 +74,6 @@ enetc_xmit_pkts(void *tx_queue, start = 0; while (nb_pkts--) { - enetc_clean_tx_ring(tx_ring); tx_ring->q_swbd[i].buffer_addr = tx_pkts[start]; txbd = ENETC_TXBD(*tx_ring, i); tx_swbd = &tx_ring->q_swbd[i]; @@ -77,6 +89,14 @@ enetc_xmit_pkts(void *tx_queue, i = 0; } + /* we're only cleaning up the Tx ring here, on the assumption that + * software is slower than hardware and hardware completed sending + * older frames out by now. + * We're also cleaning up the ring before kicking off Tx for the new + * batch to minimize chances of contention on the Tx ring + */ + enetc_clean_tx_ring(tx_ring); + tx_ring->next_to_use = i; enetc_wr_reg(tx_ring->tcir, i); return start; @@ -283,12 +303,6 @@ enetc_clean_rx_ring(struct enetc_bdr *rx_ring, union enetc_rx_bd *rxbd; uint32_t bd_status; - if (cleaned_cnt >= ENETC_RXBD_BUNDLE) { - int count = enetc_refill_rx_ring(rx_ring, cleaned_cnt); - - cleaned_cnt -= count; - } - rxbd = ENETC_RXBD(*rx_ring, i); bd_status = rte_le_to_cpu_32(rxbd->r.lstatus); if (!bd_status) @@ -315,6 +329,8 @@ enetc_clean_rx_ring(struct enetc_bdr *rx_ring, rx_frm_cnt++; } + enetc_refill_rx_ring(rx_ring, cleaned_cnt); + return rx_frm_cnt; }