22/* Copyright(c) 2018 Intel Corporation. */
33
44#include <linux/bpf_trace.h>
5+ #include <linux/stringify.h>
56#include <net/xdp_sock_drv.h>
67#include <net/xdp.h>
78
@@ -381,6 +382,69 @@ int i40e_clean_rx_irq_zc(struct i40e_ring *rx_ring, int budget)
381382 return failure ? budget : (int )total_rx_packets ;
382383}
383384
385+ static void i40e_xmit_pkt (struct i40e_ring * xdp_ring , struct xdp_desc * desc ,
386+ unsigned int * total_bytes )
387+ {
388+ struct i40e_tx_desc * tx_desc ;
389+ dma_addr_t dma ;
390+
391+ dma = xsk_buff_raw_get_dma (xdp_ring -> xsk_pool , desc -> addr );
392+ xsk_buff_raw_dma_sync_for_device (xdp_ring -> xsk_pool , dma , desc -> len );
393+
394+ tx_desc = I40E_TX_DESC (xdp_ring , xdp_ring -> next_to_use ++ );
395+ tx_desc -> buffer_addr = cpu_to_le64 (dma );
396+ tx_desc -> cmd_type_offset_bsz = build_ctob (I40E_TX_DESC_CMD_ICRC | I40E_TX_DESC_CMD_EOP ,
397+ 0 , desc -> len , 0 );
398+
399+ * total_bytes += desc -> len ;
400+ }
401+
402+ static void i40e_xmit_pkt_batch (struct i40e_ring * xdp_ring , struct xdp_desc * desc ,
403+ unsigned int * total_bytes )
404+ {
405+ u16 ntu = xdp_ring -> next_to_use ;
406+ struct i40e_tx_desc * tx_desc ;
407+ dma_addr_t dma ;
408+ u32 i ;
409+
410+ loop_unrolled_for (i = 0 ; i < PKTS_PER_BATCH ; i ++ ) {
411+ dma = xsk_buff_raw_get_dma (xdp_ring -> xsk_pool , desc [i ].addr );
412+ xsk_buff_raw_dma_sync_for_device (xdp_ring -> xsk_pool , dma , desc [i ].len );
413+
414+ tx_desc = I40E_TX_DESC (xdp_ring , ntu ++ );
415+ tx_desc -> buffer_addr = cpu_to_le64 (dma );
416+ tx_desc -> cmd_type_offset_bsz = build_ctob (I40E_TX_DESC_CMD_ICRC |
417+ I40E_TX_DESC_CMD_EOP ,
418+ 0 , desc [i ].len , 0 );
419+
420+ * total_bytes += desc [i ].len ;
421+ }
422+
423+ xdp_ring -> next_to_use = ntu ;
424+ }
425+
426+ static void i40e_fill_tx_hw_ring (struct i40e_ring * xdp_ring , struct xdp_desc * descs , u32 nb_pkts ,
427+ unsigned int * total_bytes )
428+ {
429+ u32 batched , leftover , i ;
430+
431+ batched = nb_pkts & ~(PKTS_PER_BATCH - 1 );
432+ leftover = nb_pkts & (PKTS_PER_BATCH - 1 );
433+ for (i = 0 ; i < batched ; i += PKTS_PER_BATCH )
434+ i40e_xmit_pkt_batch (xdp_ring , & descs [i ], total_bytes );
435+ for (i = batched ; i < batched + leftover ; i ++ )
436+ i40e_xmit_pkt (xdp_ring , & descs [i ], total_bytes );
437+ }
438+
439+ static void i40e_set_rs_bit (struct i40e_ring * xdp_ring )
440+ {
441+ u16 ntu = xdp_ring -> next_to_use ? xdp_ring -> next_to_use - 1 : xdp_ring -> count - 1 ;
442+ struct i40e_tx_desc * tx_desc ;
443+
444+ tx_desc = I40E_TX_DESC (xdp_ring , ntu );
445+ tx_desc -> cmd_type_offset_bsz |= (I40E_TX_DESC_CMD_RS << I40E_TXD_QW1_CMD_SHIFT );
446+ }
447+
384448/**
385449 * i40e_xmit_zc - Performs zero-copy Tx AF_XDP
386450 * @xdp_ring: XDP Tx ring
@@ -390,45 +454,30 @@ int i40e_clean_rx_irq_zc(struct i40e_ring *rx_ring, int budget)
390454 **/
391455static bool i40e_xmit_zc (struct i40e_ring * xdp_ring , unsigned int budget )
392456{
393- unsigned int sent_frames = 0 , total_bytes = 0 ;
394- struct i40e_tx_desc * tx_desc = NULL ;
395- struct xdp_desc desc ;
396- dma_addr_t dma ;
397-
398- while (budget -- > 0 ) {
399- if (!xsk_tx_peek_desc (xdp_ring -> xsk_pool , & desc ))
400- break ;
401-
402- dma = xsk_buff_raw_get_dma (xdp_ring -> xsk_pool , desc .addr );
403- xsk_buff_raw_dma_sync_for_device (xdp_ring -> xsk_pool , dma ,
404- desc .len );
405-
406- tx_desc = I40E_TX_DESC (xdp_ring , xdp_ring -> next_to_use );
407- tx_desc -> buffer_addr = cpu_to_le64 (dma );
408- tx_desc -> cmd_type_offset_bsz =
409- build_ctob (I40E_TX_DESC_CMD_ICRC
410- | I40E_TX_DESC_CMD_EOP ,
411- 0 , desc .len , 0 );
412-
413- sent_frames ++ ;
414- total_bytes += desc .len ;
415-
416- xdp_ring -> next_to_use ++ ;
417- if (xdp_ring -> next_to_use == xdp_ring -> count )
418- xdp_ring -> next_to_use = 0 ;
457+ struct xdp_desc * descs = xdp_ring -> xsk_descs ;
458+ u32 nb_pkts , nb_processed = 0 ;
459+ unsigned int total_bytes = 0 ;
460+
461+ nb_pkts = xsk_tx_peek_release_desc_batch (xdp_ring -> xsk_pool , descs , budget );
462+ if (!nb_pkts )
463+ return false;
464+
465+ if (xdp_ring -> next_to_use + nb_pkts >= xdp_ring -> count ) {
466+ nb_processed = xdp_ring -> count - xdp_ring -> next_to_use ;
467+ i40e_fill_tx_hw_ring (xdp_ring , descs , nb_processed , & total_bytes );
468+ xdp_ring -> next_to_use = 0 ;
419469 }
420470
421- if (tx_desc ) {
422- /* Request an interrupt for the last frame and bump tail ptr. */
423- tx_desc -> cmd_type_offset_bsz |= (I40E_TX_DESC_CMD_RS <<
424- I40E_TXD_QW1_CMD_SHIFT );
425- i40e_xdp_ring_update_tail (xdp_ring );
471+ i40e_fill_tx_hw_ring (xdp_ring , & descs [nb_processed ], nb_pkts - nb_processed ,
472+ & total_bytes );
426473
427- xsk_tx_release (xdp_ring -> xsk_pool );
428- i40e_update_tx_stats (xdp_ring , sent_frames , total_bytes );
429- }
474+ /* Request an interrupt for the last frame and bump tail ptr. */
475+ i40e_set_rs_bit (xdp_ring );
476+ i40e_xdp_ring_update_tail (xdp_ring );
477+
478+ i40e_update_tx_stats (xdp_ring , nb_pkts , total_bytes );
430479
431- return !! budget ;
480+ return true ;
432481}
433482
434483/**
0 commit comments