enetc: Simply TX ring credits counting logic
According to the RM rings can hold at most ring_size - 1 descriptors at any time. No additional logic is needed since iflib already respects this constrain. Thanks to that the pidx == cidx situation is not ambiguous and indicates an empty ring. Use that to simplify the logic that calculates the amount of processed frames. Obtained from: Semihalf Sponsored by: Alstom Group
This commit is contained in:
parent
f485d733e8
commit
a6bda3e1ef
@ -52,8 +52,7 @@ struct enetc_tx_queue {
|
||||
union enetc_tx_bd *ring;
|
||||
uint64_t ring_paddr;
|
||||
|
||||
qidx_t next_to_clean;
|
||||
bool ring_full;
|
||||
qidx_t cidx;
|
||||
|
||||
struct if_irq irq;
|
||||
};
|
||||
|
@ -503,8 +503,7 @@ enetc_tx_queues_alloc(if_ctx_t ctx, caddr_t *vaddrs, uint64_t *paddrs,
|
||||
queue->sc = sc;
|
||||
queue->ring = (union enetc_tx_bd*)(vaddrs[i]);
|
||||
queue->ring_paddr = paddrs[i];
|
||||
queue->next_to_clean = 0;
|
||||
queue->ring_full = false;
|
||||
queue->cidx = 0;
|
||||
}
|
||||
|
||||
return (0);
|
||||
@ -1125,8 +1124,6 @@ enetc_isc_txd_encap(void *data, if_pkt_info_t ipi)
|
||||
|
||||
desc->flags |= ENETC_TXBD_FLAGS_F;
|
||||
ipi->ipi_new_pidx = pidx;
|
||||
if (pidx == queue->next_to_clean)
|
||||
queue->ring_full = true;
|
||||
|
||||
return (0);
|
||||
}
|
||||
@ -1144,28 +1141,35 @@ enetc_isc_txd_credits_update(void *data, uint16_t qid, bool clear)
|
||||
{
|
||||
struct enetc_softc *sc = data;
|
||||
struct enetc_tx_queue *queue;
|
||||
qidx_t next_to_clean, next_to_process;
|
||||
int clean_count;
|
||||
int cidx, hw_cidx, count;
|
||||
|
||||
queue = &sc->tx_queues[qid];
|
||||
next_to_process =
|
||||
ENETC_TXQ_RD4(sc, qid, ENETC_TBCIR) & ENETC_TBCIR_IDX_MASK;
|
||||
next_to_clean = queue->next_to_clean;
|
||||
hw_cidx = ENETC_TXQ_RD4(sc, qid, ENETC_TBCIR) & ENETC_TBCIR_IDX_MASK;
|
||||
cidx = queue->cidx;
|
||||
|
||||
if (next_to_clean == next_to_process && !queue->ring_full)
|
||||
/*
|
||||
* RM states that the ring can hold at most ring_size - 1 descriptors.
|
||||
* Thanks to that we can assume that the ring is empty if cidx == pidx.
|
||||
* This requirement is guaranteed implicitly by iflib as it will only
|
||||
* encap a new frame if we have at least nfrags + 2 descriptors available
|
||||
* on the ring. This driver uses at most one additional descriptor for
|
||||
* VLAN tag insertion.
|
||||
* Also RM states that the TBCIR register is only updated once all
|
||||
* descriptors in the chain have been processed.
|
||||
*/
|
||||
if (cidx == hw_cidx)
|
||||
return (0);
|
||||
|
||||
if (!clear)
|
||||
return (1);
|
||||
|
||||
clean_count = next_to_process - next_to_clean;
|
||||
if (clean_count <= 0)
|
||||
clean_count += sc->tx_queue_size;
|
||||
count = hw_cidx - cidx;
|
||||
if (count < 0)
|
||||
count += sc->tx_queue_size;
|
||||
|
||||
queue->next_to_clean = next_to_process;
|
||||
queue->ring_full = false;
|
||||
queue->cidx = hw_cidx;
|
||||
|
||||
return (clean_count);
|
||||
return (count);
|
||||
}
|
||||
|
||||
static int
|
||||
|
Loading…
x
Reference in New Issue
Block a user