diff --git a/drivers/net/ethernet/cadence/macb.h b/drivers/net/ethernet/cadence/macb.h index f797244f576416..90c0803c65c655 100644 --- a/drivers/net/ethernet/cadence/macb.h +++ b/drivers/net/ethernet/cadence/macb.h @@ -1259,6 +1259,7 @@ struct macb_queue { void *rx_buffers; struct napi_struct napi_rx; struct queue_stats stats; + atomic_t full_refill; }; struct ethtool_rx_fs_item { diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c index 30f0ea8c435686..913a58c969376e 100644 --- a/drivers/net/ethernet/cadence/macb_main.c +++ b/drivers/net/ethernet/cadence/macb_main.c @@ -775,11 +775,18 @@ static void macb_mac_link_up(struct phylink_config *config, /* Initialize rings & buffers as clearing MACB_BIT(TE) in link down * cleared the pipeline and control registers. */ - macb_init_buffers(bp); for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) + atomic_set(&queue->full_refill, -1); + + bp->macbgem_ops.mog_init_rings(bp); + macb_init_buffers(bp); + + for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) { + atomic_set(&queue->full_refill, bp->rx_ring_size); queue_writel(queue, IER, bp->rx_intr_mask | MACB_TX_INT_FLAGS | MACB_BIT(HRESP)); + } } macb_or_gem_writel(bp, NCFGR, ctrl); @@ -1327,8 +1334,9 @@ static void gem_rx_refill(struct macb_queue *queue) struct macb *bp = queue->bp; struct macb_dma_desc *desc; - while (CIRC_SPACE(queue->rx_prepared_head, queue->rx_tail, - bp->rx_ring_size) > 0) { + while (atomic_dec_if_positive(&queue->full_refill) >= 0 || + ((CIRC_SPACE(queue->rx_prepared_head, queue->rx_tail, bp->rx_ring_size) > 0) && + (atomic_read(&queue->full_refill) != -1))) { entry = macb_rx_ring_wrap(bp, queue->rx_prepared_head); /* Make hw descriptor updates visible to CPU */ @@ -1453,6 +1461,7 @@ static int gem_rx(struct macb_queue *queue, struct napi_struct *napi, queue->stats.rx_dropped++; break; } + /* now everything is ready for receiving packet */ queue->rx_skbuff[entry] = NULL; len = ctrl & bp->rx_frm_len_mask;