lists.openwall.net | lists / announce owl-users owl-dev john-users john-dev passwdqc-users yescrypt popa3d-users / oss-security kernel-hardening musl sabotage tlsify passwords / crypt-dev xvendor / Bugtraq Full-Disclosure linux-kernel linux-netdev linux-ext4 linux-hardening linux-cve-announce PHC | |
Open Source and information security mailing list archives
| ||
|
Message-Id: <20230502220818.691444-2-shenwei.wang@nxp.com> Date: Tue, 2 May 2023 17:08:18 -0500 From: Shenwei Wang <shenwei.wang@....com> To: Wei Fang <wei.fang@....com>, "David S. Miller" <davem@...emloft.net>, Eric Dumazet <edumazet@...gle.com>, Jakub Kicinski <kuba@...nel.org>, Paolo Abeni <pabeni@...hat.com> Cc: Shenwei Wang <shenwei.wang@....com>, Clark Wang <xiaoning.wang@....com>, NXP Linux Team <linux-imx@....com>, Alexei Starovoitov <ast@...nel.org>, Daniel Borkmann <daniel@...earbox.net>, Jesper Dangaard Brouer <hawk@...nel.org>, John Fastabend <john.fastabend@...il.com>, Alexander Lobakin <alexandr.lobakin@...el.com>, netdev@...r.kernel.org, linux-kernel@...r.kernel.org, imx@...ts.linux.dev Subject: [PATCH v2 net 2/2] net: fec: restructuring the functions to avoid forward declarations The patch reorganizes functions related to XDP frame transmission, moving them above the fec_enet_run_xdp implementation. This eliminates the need for forward declarations of these functions. Fixes: 6d6b39f180b8 ("net: fec: add initial XDP support") Signed-off-by: Shenwei Wang <shenwei.wang@....com> --- drivers/net/ethernet/freescale/fec_main.c | 216 +++++++++++----------- 1 file changed, 108 insertions(+), 108 deletions(-) diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c index 42ec6ca3bf03..14f9907f3ca2 100644 --- a/drivers/net/ethernet/freescale/fec_main.c +++ b/drivers/net/ethernet/freescale/fec_main.c @@ -1511,6 +1511,114 @@ static void fec_enet_update_cbd(struct fec_enet_priv_rx_q *rxq, bdp->cbd_bufaddr = cpu_to_fec32(phys_addr); } +static int +fec_enet_xdp_get_tx_queue(struct fec_enet_private *fep, int index) +{ + if (unlikely(index < 0)) + return 0; + + return (index % fep->num_tx_queues); +} + +static int fec_enet_txq_xmit_frame(struct fec_enet_private *fep, + struct fec_enet_priv_tx_q *txq, + struct xdp_frame *frame) +{ + unsigned int index, status, estatus; + struct bufdesc *bdp, *last_bdp; + dma_addr_t dma_addr; + int entries_free; + + entries_free = fec_enet_get_free_txdesc_num(txq); + if (entries_free < MAX_SKB_FRAGS + 1) { + netdev_err(fep->netdev, "NOT enough BD for SG!\n"); + xdp_return_frame(frame); + return NETDEV_TX_BUSY; + } + + /* Fill in a Tx ring entry */ + bdp = txq->bd.cur; + last_bdp = bdp; + status = fec16_to_cpu(bdp->cbd_sc); + status &= ~BD_ENET_TX_STATS; + + index = fec_enet_get_bd_index(bdp, &txq->bd); + + dma_addr = dma_map_single(&fep->pdev->dev, frame->data, + frame->len, DMA_TO_DEVICE); + if (dma_mapping_error(&fep->pdev->dev, dma_addr)) + return FEC_ENET_XDP_CONSUMED; + + status |= (BD_ENET_TX_INTR | BD_ENET_TX_LAST); + if (fep->bufdesc_ex) + estatus = BD_ENET_TX_INT; + + bdp->cbd_bufaddr = cpu_to_fec32(dma_addr); + bdp->cbd_datlen = cpu_to_fec16(frame->len); + + if (fep->bufdesc_ex) { + struct bufdesc_ex *ebdp = (struct bufdesc_ex *)bdp; + + if (fep->quirks & FEC_QUIRK_HAS_AVB) + estatus |= FEC_TX_BD_FTYPE(txq->bd.qid); + + ebdp->cbd_bdu = 0; + ebdp->cbd_esc = cpu_to_fec32(estatus); + } + + index = fec_enet_get_bd_index(last_bdp, &txq->bd); + txq->tx_skbuff[index] = NULL; + + /* Send it on its way. Tell FEC it's ready, interrupt when done, + * it's the last BD of the frame, and to put the CRC on the end. + */ + status |= (BD_ENET_TX_READY | BD_ENET_TX_TC); + bdp->cbd_sc = cpu_to_fec16(status); + + /* If this was the last BD in the ring, start at the beginning again. */ + bdp = fec_enet_get_nextdesc(last_bdp, &txq->bd); + + txq->bd.cur = bdp; + + return 0; +} + +static int fec_enet_xdp_xmit(struct net_device *dev, + int num_frames, + struct xdp_frame **frames, + u32 flags) +{ + struct fec_enet_private *fep = netdev_priv(dev); + struct fec_enet_priv_tx_q *txq; + int cpu = smp_processor_id(); + unsigned int sent_frames = 0; + struct netdev_queue *nq; + unsigned int queue; + int i; + + queue = fec_enet_xdp_get_tx_queue(fep, cpu); + txq = fep->tx_queue[queue]; + nq = netdev_get_tx_queue(fep->netdev, queue); + + __netif_tx_lock(nq, cpu); + + for (i = 0; i < num_frames; i++) { + if (fec_enet_txq_xmit_frame(fep, txq, frames[i]) != 0) + break; + sent_frames++; + } + + /* Make sure the update to bdp and tx_skbuff are performed. */ + wmb(); + + /* Trigger transmission start */ + writel(0, txq->bd.reg_desc_active); + + __netif_tx_unlock(nq); + + return sent_frames; +} + static u32 fec_enet_run_xdp(struct fec_enet_private *fep, struct bpf_prog *prog, struct xdp_buff *xdp, struct fec_enet_priv_rx_q *rxq, int index) @@ -3777,114 +3885,6 @@ static int fec_enet_bpf(struct net_device *dev, struct netdev_bpf *bpf) } } -static int -fec_enet_xdp_get_tx_queue(struct fec_enet_private *fep, int index) -{ - if (unlikely(index < 0)) - return 0; - - return (index % fep->num_tx_queues); -} - -static int fec_enet_txq_xmit_frame(struct fec_enet_private *fep, - struct fec_enet_priv_tx_q *txq, - struct xdp_frame *frame) -{ - unsigned int index, status, estatus; - struct bufdesc *bdp, *last_bdp; - dma_addr_t dma_addr; - int entries_free; - - entries_free = fec_enet_get_free_txdesc_num(txq); - if (entries_free < MAX_SKB_FRAGS + 1) { - netdev_err(fep->netdev, "NOT enough BD for SG!\n"); - xdp_return_frame(frame); - return NETDEV_TX_BUSY; - } - - /* Fill in a Tx ring entry */ - bdp = txq->bd.cur; - last_bdp = bdp; - status = fec16_to_cpu(bdp->cbd_sc); - status &= ~BD_ENET_TX_STATS; - - index = fec_enet_get_bd_index(bdp, &txq->bd); - - dma_addr = dma_map_single(&fep->pdev->dev, frame->data, - frame->len, DMA_TO_DEVICE); - if (dma_mapping_error(&fep->pdev->dev, dma_addr)) - return FEC_ENET_XDP_CONSUMED; - - status |= (BD_ENET_TX_INTR | BD_ENET_TX_LAST); - if (fep->bufdesc_ex) - estatus = BD_ENET_TX_INT; - - bdp->cbd_bufaddr = cpu_to_fec32(dma_addr); - bdp->cbd_datlen = cpu_to_fec16(frame->len); - - if (fep->bufdesc_ex) { - struct bufdesc_ex *ebdp = (struct bufdesc_ex *)bdp; - - if (fep->quirks & FEC_QUIRK_HAS_AVB) - estatus |= FEC_TX_BD_FTYPE(txq->bd.qid); - - ebdp->cbd_bdu = 0; - ebdp->cbd_esc = cpu_to_fec32(estatus); - } - - index = fec_enet_get_bd_index(last_bdp, &txq->bd); - txq->tx_skbuff[index] = NULL; - - /* Send it on its way. Tell FEC it's ready, interrupt when done, - * it's the last BD of the frame, and to put the CRC on the end. - */ - status |= (BD_ENET_TX_READY | BD_ENET_TX_TC); - bdp->cbd_sc = cpu_to_fec16(status); - - /* If this was the last BD in the ring, start at the beginning again. */ - bdp = fec_enet_get_nextdesc(last_bdp, &txq->bd); - - txq->bd.cur = bdp; - - return 0; -} - -static int fec_enet_xdp_xmit(struct net_device *dev, - int num_frames, - struct xdp_frame **frames, - u32 flags) -{ - struct fec_enet_private *fep = netdev_priv(dev); - struct fec_enet_priv_tx_q *txq; - int cpu = smp_processor_id(); - unsigned int sent_frames = 0; - struct netdev_queue *nq; - unsigned int queue; - int i; - - queue = fec_enet_xdp_get_tx_queue(fep, cpu); - txq = fep->tx_queue[queue]; - nq = netdev_get_tx_queue(fep->netdev, queue); - - __netif_tx_lock(nq, cpu); - - for (i = 0; i < num_frames; i++) { - if (fec_enet_txq_xmit_frame(fep, txq, frames[i]) != 0) - break; - sent_frames++; - } - - /* Make sure the update to bdp and tx_skbuff are performed. */ - wmb(); - - /* Trigger transmission start */ - writel(0, txq->bd.reg_desc_active); - - __netif_tx_unlock(nq); - - return sent_frames; -} - static const struct net_device_ops fec_netdev_ops = { .ndo_open = fec_enet_open, .ndo_stop = fec_enet_close, -- 2.34.1
Powered by blists - more mailing lists