diff options
Diffstat (limited to 'drivers/net/ethernet/socionext/netsec.c')
-rw-r--r-- | drivers/net/ethernet/socionext/netsec.c | 14 |
1 files changed, 12 insertions, 2 deletions
diff --git a/drivers/net/ethernet/socionext/netsec.c b/drivers/net/ethernet/socionext/netsec.c index 1503cc9ec6e2..19d20a6d0d44 100644 --- a/drivers/net/ethernet/socionext/netsec.c +++ b/drivers/net/ethernet/socionext/netsec.c @@ -631,6 +631,7 @@ static void netsec_set_rx_de(struct netsec_priv *priv, static bool netsec_clean_tx_dring(struct netsec_priv *priv) { struct netsec_desc_ring *dring = &priv->desc_ring[NETSEC_RING_TX]; + struct xdp_frame_bulk bq; struct netsec_de *entry; int tail = dring->tail; unsigned int bytes; @@ -639,8 +640,11 @@ static bool netsec_clean_tx_dring(struct netsec_priv *priv) spin_lock(&dring->lock); bytes = 0; + xdp_frame_bulk_init(&bq); entry = dring->vaddr + DESC_SZ * tail; + rcu_read_lock(); /* need for xdp_return_frame_bulk */ + while (!(entry->attr & (1U << NETSEC_TX_SHIFT_OWN_FIELD)) && cnt < DESC_NUM) { struct netsec_desc *desc; @@ -665,7 +669,10 @@ static bool netsec_clean_tx_dring(struct netsec_priv *priv) dev_kfree_skb(desc->skb); } else { bytes += desc->xdpf->len; - xdp_return_frame(desc->xdpf); + if (desc->buf_type == TYPE_NETSEC_XDP_TX) + xdp_return_frame_rx_napi(desc->xdpf); + else + xdp_return_frame_bulk(desc->xdpf, &bq); } next: /* clean up so netsec_uninit_pkt_dring() won't free the skb @@ -684,6 +691,9 @@ next: entry = dring->vaddr + DESC_SZ * tail; cnt++; } + xdp_flush_frame_bulk(&bq); + + rcu_read_unlock(); spin_unlock(&dring->lock); @@ -1304,7 +1314,7 @@ static int netsec_setup_rx_dring(struct netsec_priv *priv) goto err_out; } - err = xdp_rxq_info_reg(&dring->xdp_rxq, priv->ndev, 0); + err = xdp_rxq_info_reg(&dring->xdp_rxq, priv->ndev, 0, priv->napi.napi_id); if (err) goto err_out; |